Is there a way to know that nodeunit has finished all tests?

I need to run some code after nodeunit successfully passed all tests. I'm testing some Firebase wrappers and Firebase reference blocks exiting nodeunit after all test are run.

I am looking for some hook or callback to run after all unit tests are passed. So I can terminate Firebase process in order nodeunit to be able to exit.

For a recent project, we counted the tests by iterating exports, then called tearDown to count the completions. After the last test exits, we called process.exit().

See the spec for full details. Note that this went at the end of the file (after all the tests were added onto exports)

(function(exports) {
  // firebase is holding open a socket connection
  // this just ends the process to terminate it
  var total = 0, expectCount = countTests(exports);
  exports.tearDown = function(done) {
    if( ++total === expectCount ) {
      setTimeout(function() {
        process.exit();
      }, 500);
    }
    done();
  };

  function countTests(exports) {
    var count = 0;
    for(var key in exports) {
      if( key.match(/^test/) ) {
        count++;
      }
    }
    return count;
  }
})(exports);

Didn't found a right way to do it.

There is my temporary solution:

//Put a *LAST* test to clear all if needed:
exports.last_test = function(test){
    //do_clear_all_things_if_needed();
    setTimeout(process.exit, 500); // exit in 500 milli-seconds    
    test.done(); 
} 

In my case, this is used to make sure DB connection or some network connect get killed any way. The reason it works is because nodeunit run tests in series.

It's not the best, even not the good way, just to let the test exit.

For nodeunit 0.9.0

As per nodeunit docs I can't seem to find a way to provide a callback after all tests have ran.

I suggest that you use Grunt so you can create a test workflow with tasks, for example:

  1. Install the command line tool: npm install -g grunt-cli
  2. Install grunt to your project npm install grunt --save-dev
  3. Install the nodeunit grunt plugin: npm install grunt-contrib-nodeunit --save-dev
  4. Create a Gruntfile.js like the following:

    module.exports = function(grunt) {
    
        grunt.initConfig({
            nodeunit : {
                all : ['tests/*.js'] //point to where your tests are
            }
        });
    
        grunt.loadNpmTasks('grunt-contrib-nodeunit');
    
        grunt.registerTask('test', [
            'nodeunit'
        ]);
    };
    
  5. Create your custom task that will be run after the tests by changing your grunt file to the following:

    module.exports = function(grunt) {
    
        grunt.initConfig({
            nodeunit : {
                all : ['tests/*.js'] //point to where your tests are
            }
        });
    
        grunt.loadNpmTasks('grunt-contrib-nodeunit');
    
        //this is just an example you can do whatever you want
        grunt.registerTask('generate-build-json', 'Generates a build.json file containing date and time info of the build', function() {
            fs.writeFileSync('build.json', JSON.stringify({
                platform: os.platform(),
                arch: os.arch(),
                timestamp: new Date().toISOString()
            }, null, 4));
    
            grunt.log.writeln('File build.json created.');
        });
    
        grunt.registerTask('test', [
            'nodeunit',
            'generate-build-json'
        ]);
    };
    
  6. Run your test tasks with grunt test

I came across another solution how to deal with this solution. I have to say the all answers here are correct. However when inspecting grunt I found out that Grunt is running nodeunit tests via reporter and the reporter offers a callback option when all tests are finished. It could be done something like this:

in folder

test_scripts/
   some_test.js

test.js can contain something like this:

//loads default reporter, but any other can be used
var reporter = require('nodeunit').reporters.default;
// safer exit, but process.exit(0) will do the same in most cases
var exit = require('exit');

reporter.run(['test/basic.js'], null, function(){
    console.log(' now the tests are finished');
    exit(0);
});

the script can be added to let's say package.json in script object

  "scripts": {
    "nodeunit": "node scripts/some_test.js",
  },

now it can be done as

npm run nodeunit

the tests in some_tests.js can be chained or it can be run one by one using npm