How to finish/kill Mocha/Istanbul test cycle with Node.js - node.js

I've been working on getting an Azure Mobile App with Node.js backend running locally and testable. I finally got everything working well and started writing my tests. Then, I learned about Istanbul/NYC for testing code coverage.
All appears to be working well, and I am able to get the code coverage file generated for all my *.js files, but only after I manually press Ctrl+C.
Is this the normal way for a set of mocha tests to end? It would seem that there would/should be some way to get to the end of a set of tests and auto-kill the Node.js/express server that was created for the test session.
I'm new to the nuts-and-bolts side of Node.js/express/mocha/nyc. Is my expectation wrong? Is there a way to do what I'd like?

I'm not sure where you are lifting your server (server.listen) but stopping your server on a "global" after should be enough.
What I usually do is create a bootstrap.test.js and specify what should happen before and after tests there and run mocha like this:
mocha /test/bootstrap.test.js /test/unit/**/*.test.js /test/integration/**/*.test.js.
You need to make sure that that after is not inside a describe, so it runs after all tests have completed.
So your bootstrap.test.js should look something like this:
/*
imports and stuff
*/
before(function () {
// LIFT YOUR SERVER //
});
after(function () {
server.close();
});
EDIT:
As for the programmatic equivalent of Ctrl-c, that is process.exit(0)

Related

How to run multiple integration tests using mocha recursively without getting their hooks all combined?

I have made a few integration test using mocha which run fine when run independently but when i try to run them using : mocha test --recursively .
The behaviour I noticed here is that all the after hooks (probably the before too) are getting combined.
I drop my db in the after hook of each test so I check in between tests and I can find data from the previous tests.
It gets cleared up after the last test somehow.
I have already tried importing them into one file but even that won't serve the purpose.
Here are my hooks.
before(async () => {
app.set('port', SERVER_PORT);
server = http.createServer(app);
server.listen(SERVER_PORT, () => console.log(`API running on localhost:${SERVER_PORT}`));
// Initial feeding of the database
await dookie.push('mongodb://localhost:27017/tests', SEEDDATA);
});
after(async () => {
await mongoose.connection.db.dropDatabase();
server.close();
process.exit(0);
});
THANKS
Use jest as it provides the functionality you're looking for inbuilt.
It's hard to tell what is wrong with your tests without having a closer look at the code, so I'm going to drop here a few ideas that come to my mind, with no guarantee that anything will help.
Possibility 1
Use beforeEach and afterEach rather than before and after. This will ensure that your DB cleanup code is executed after each test, rather than after the last test in a describe function block. Details here.
Possibility 2
You are running your tests in multiple threads with mocha-parallel-tests or some other tool. Make sure that the tests where the DB is being accessed are not being parallelized.
Possibility 3
Your db.dropDatabase call returns before the database is actually dropped, while the request is still pending. You'll have to check your connection or database settings.
If nothing helps, try inserting log statements at the start of each unit test and before/after hook, this will help you understand when the code is actually being run and see what is happening in the wrong order.

Adding a default before() function for all the test cases (Mocha)

I'm writing functions for my node.js server using TDD(Mocha). For connecting to the database I'm doing
before(function(done){
db.connect(function(){
done();
});
});
and I'm running the test cases using make test and have configured my makefile to run all the js files in that particular folder using mocha *.js
But for each js file I'll have to make a separate connection to the database, otherwise my test cases fail since they do not share common scope with other test files.
So the question is, Is there anything like beforeAll() that would just simply connect once to the database and then run all the test cases? Any help/suggestion appreciated.
You can setup your db connection as a module that each of the Mocha test modules imports.
var db = require('./db');
A good database interface will queue commands you send to it before it has finished connecting. You can use that to your advantage here.
In your before call, simply do something that amounts to a no op. In SQL that would be something simple like a raw query of SELECT 1. You don't care about the result. The return of the query just signifies that the database is ready.
Since each Mocha module uses the same database module, it'll only connect once.
Use this in each of your test modules:
before(function(done) {
db.no_op(done);
});
Then define db.no_op to be a function that performs the no op and takes a callback function.

Mocha browser tests with Node.js command-line runner?

I have a suite of client-side Mocha tests that currently run with the browser test runner. But I also have a suite of server-side Mocha tests that run with the Node.js command-line test runner.
I know I can run the client-side tests from the command-line in a headless browser like PhantomJS (e.g. like this), but they'd still run separately from the server-side tests.
Is there any way to run the client-side tests as part of the command-line run?
E.g. always run both sets of tests, and have one combined output like "all 100 tests passed" or "2 tests failed" — across both client-side and server-side suites.
I imagine if this were possible, there'd need to be some sort of "proxy" layer to dynamically describe to the command-line runner each browser test, and notify it of each result (maybe even any console.log output too) as the tests ran in the browser.
Does there exist anything that achieves this? I've had a hard time finding anything. Thanks!
I use Zombie for this. There's surely a way to do it with Phantom too. Just write your client-side tests under the same directory as your server-side tests and they'll get picked up by Mocha and executed along with the rest.
I'm not sure whether you need some sample test code but here's some just in case:
var app = require('../server').app; // Spin up your server for testing
var Browser = require('zombie');
var should = require('should');
describe('Some test suite', function () {
it('should do what you expect', function (done) {
var browser = new Browser();
browser.visit('http://localhost:3000', function (err) {
// Let's say this is a log in page
should.not.exist(err);
browser
.fill('#username', 'TestUser')
.fill('#password', 'TestPassword')
.pressButton('#login', function (err) {
should.not.exist(err);
// etc...
return done();
});
});
});
});

Why nodejs test case with nodeunit keep loading in webstorm after successfully passed the test cases?

I am working on nodejs project. And I am using nodeunit npm module to test my server-side codebase. I am using Webstorm as an editor for writing my codes and also testing the server-side code with the help of nodeunit module.
Everything is working perfectly, my test cases passed correctly but the test cases progress is keep loading in Webstorm status panel. I have manually to stop that each time. Does anybody have any idea on this?
Are you calling done() at the end? For example
exports.globalSetterTest = function(test){
var app = require('../helpers/globalsetter');
app.setData("abc");
var res = app.getData();
test.equal(res, "abc", "msg");
test.done();
};
I have the same setup as you and here are some sample tests I wrote.
https://github.com/captainchung/webstormNodeUnitTests/blob/master/test/spec.js
I had the same problem: all nodeunit tests pass, but Webstorm's spinner keeps going forever. I solved it by explicitly closing the database connection that was opened by the code under test -- something I didn't have to do outside test code because my database driver prefers to keep the connections alive in a connection pool.

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?
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.
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.

Resources