Automate Jasmine-Node and express.js
Asked Answered
Y

4

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?

Youth answered 1/11, 2012 at 11:38 Comment(2)
What version of express are you running?Metternich
I'm using version 3.x (3.0.2 right now).Youth
E
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();
    }
});
Erfert answered 14/11, 2012 at 12:17 Comment(5)
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 :)Youth
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 ;)Erfert
Sorry, found a forgotten app.use(express.logger('dev')); Thanks ^^Youth
No worries, that output looked pretty familiar ;DErfert
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.Conklin
L
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.

Livingston answered 1/11, 2012 at 16:50 Comment(3)
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?Youth
do you have an example of this?Anarchist
Here is an example of the output: pastebin.com/9qF1NeU1 and here of the server_spec.coffee: pastebin.com/uvcBuTiyYouth
B
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

Bellaude answered 10/11, 2012 at 23:15 Comment(1)
doesn't get it working, the snippet from @ShadowCloud is nice :)Youth
T
-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 ;)

Thinner answered 12/10, 2014 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.