8

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?

Kris Erickson
  • 33,454
  • 26
  • 120
  • 175
  • were you thinking about using CI server instead of grunt for these tasks? – jan salawa Apr 09 '13 at 17:39
  • Ultimately the goal is Continuous Integration and then Continuous Deployment but the build task depends upon grunt so getting that working first is step one. – Kris Erickson Apr 10 '13 at 15:25
  • You should check this question I asked: http://stackoverflow.com/questions/15230090/nodemon-like-task-in-grunt-execute-node-process-and-watch – Augustin Riedinger Apr 16 '13 at 15:55

2 Answers2

11

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.

user568109
  • 47,225
  • 17
  • 99
  • 123
1

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.

Sebastian vom Meer
  • 5,005
  • 2
  • 28
  • 36