8

I created a simple Webapp using express.js and want to test it with jasmine-node. Works fine so far but my problem is that I have to start the server manually every time before I can run my tests.

Could you help me on how to write a spec-helper that runs the server (with another port then my development one) just for the tests and then kills it afterwards?

Philip Kirkbride
  • 21,381
  • 38
  • 125
  • 225
optikfluffel
  • 2,538
  • 4
  • 20
  • 27

4 Answers4

17

This is what I do:

I have a server.js file inside the root of my node project that sets up the node application server (with express) and exports 2 methods:

exports.start = function( config, readyCallback ) {

    if(!this.server) {

        this.server = app.listen( config.port, function() {

            console.log('Server running on port %d in %s mode', config.port, app.settings.env);

            // callback to call when the server is ready
            if(readyCallback) {
                readyCallback();
            }
        });
    }
};

exports.close = function() {
    this.server.close();
};

The app.js file will be simple at this point:

var server = require('./server');
server.start( { port: 8000 } );

So the files/folder basic structure would be the following:

src
   app.js
   server.js

Having this separation will allow you to run the server normally:

node src/app.js

..and/or require it from a custom node script, which could be a node script (or a jake/grunt/whatever task) that executes your tests like this:

/** my-test-task.js */

// util that spawns a child process
var spawn = require('child_process').spawn;

// reference to our node application server
var server = require('./path/to/server.js');

// starts the server
server.start( { port: 8000 }, function() {

    // on server ready launch the jasmine-node process with your test file
    var jasmineNode = spawn('jasmine-node', [ '.path/to/test/file.js' ]);

    // logs process stdout/stderr to the console
    function logToConsole(data) {
        console.log(String(data));
    }
    jasmineNode.stdout.on('data', logToConsole);
    jasmineNode.stderr.on('data', logToConsole);

    jasmineNode.on('exit', function(exitCode) {
        // when jasmine-node is done, shuts down the application server
        server.close();
    }
});
BFil
  • 12,966
  • 3
  • 44
  • 48
  • Ok I got it so far. If you tell me now how to get rid of the server-output (like: _GET / 200 46ms - 167_) in my test-output everythings fine :) – optikfluffel Nov 14 '12 at 14:52
  • Seems like you have something configured in your node server app that logs the requests, a profiler middleware for express maybe? Check your express server code ;) – BFil Nov 14 '12 at 15:03
  • Sorry, found a forgotten app.use(express.logger('dev')); Thanks ^^ – optikfluffel Nov 14 '12 at 15:08
  • No worries, that output looked pretty familiar ;D – BFil Nov 14 '12 at 15:09
  • I would like to add that `server.close()` might fail due to another subsystem not closing. Drove me nuts that the unit test triggered the DB, so the unit test alone terminated, the server alone terminated but together, cause the unit test opened the database (yeah, I know, mocking, ...) the server process didn't terminate anymore after closing the server. – Giszmo Aug 12 '15 at 06:12
0

I use Mocha - which is damn similar - but the same principle should apply: you could try requireing your app.js file in a 'beforeEach' hook inside the main describe. That should fire it up for you.

floatingLomas
  • 8,553
  • 2
  • 21
  • 27
  • OK then it fires up and the tests are running but it doesn't stop and fails if I use --autotest option (or do similar) and it doesn't stop if I only want to run the tests once. On top of that I now have the http-output (GET / 200 6ms - 167) in my test output. How do I get rid of this? – optikfluffel Nov 02 '12 at 08:30
  • do you have an example of this? – chovy Nov 10 '12 at 07:38
  • Here is an example of the output: http://pastebin.com/9qF1NeU1 and here of the server_spec.coffee: http://pastebin.com/uvcBuTiy – optikfluffel Nov 10 '12 at 19:10
0

Assuming you use some code that invokes app.listen() in server.js, don't require the file on each run but only once and then have two functions like

startServer = -> app.listen(3000)
stopServer = -> app.close()

Then you can use these in beforeEach and afterEach

Marcus Ilgner
  • 6,935
  • 2
  • 30
  • 44
-1

If you want then to go one step further in automating your testing while you develop, you can go to your terminal line and execute

jasmine-node . --autotest

Jasmine then will stay listening to every file inside your project and whenever you make changes to one it will tell if that piece of your code breaks any of your tests ;)