Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get grunt.js to start an express app for testing

My current situation is that I use grunt to make a production version of my express app (minimize and merge all the js/css, copy all the files in place) and then I have to run a script which sets an environment variables (my app only serves the test harness when running in TEST mode), creates an empty Mongo test database and then calls npm start on the application directory, and then I manually have to run the tests from either Chrome or Phantom, what I want to do is have grunt set the environment variable and run the server, run the tests, and then stop the server (in the future if all is successful it would be nice to have it deploy as well). However when I try to run the app in grunt, it gets stopped as soon as it is completed.

How do I have grunt start the app, wait until it is started and then run tests?

like image 222
Kris Erickson Avatar asked Apr 07 '13 00:04

Kris Erickson


2 Answers

If you check grunt-express which is a plugin for express web-server tasks via grunt.

express-keepalive

Note that this server only runs as long as grunt is running. Once grunt's tasks have completed, the web server stops. This behavior can be changed by appending a express-keepalive task at the end of your task list like so

grunt.registerTask('myServer', ['express', 'express-keepalive']);
Now when you run grunt myServer, your express server will be kept alive until you manually terminate it.

Such feature can also be enabled ad-hoc by running the task like grunt express express-keepalive.

This design gives you the flexibility to use grunt-express in conjunction with another task that is run immediately afterwards, like the grunt-contrib-qunit plugin qunit task. If we force express task to be always async, such use case can no longer happen.

From the guide grunt-contrib-qunit package is used to run QUnit unit tests in a headless PhantomJS instance. Also mind the last line, if you force express to be always async it would be of no use.

npm link for grunt-express.

like image 142
user568109 Avatar answered Nov 15 '22 16:11

user568109


I'm not sure if I understand your problem correctly, but probably this helps:

Do you know about Grunt's async function? For some time I used the following approach to start (and stop) my Express app. I used it with watch, so it automatically restarted on save. In this case you have to set watch's nospawn option to true.

var server = null;
grunt.registerTask('server', 'Start server', function() {
  var done = this.async();
  if (server !== null) {
    server.close();
    clearCache();
  }
  var app = require('./my-express-app.js');
  server = http.createServer(app).listen(app.get('port'), function(){
    done();
  });
});

function clearCache() {
  for (key in require.cache) {
    if (key.indexOf(__dirname + '/node_modules/') == -1) {
      delete require.cache[key];
    }
  }
}

It is ugly because of this require-cache-hack. However, it works.

like image 45
Sebastian vom Meer Avatar answered Nov 15 '22 17:11

Sebastian vom Meer