I've got a problem whereas sometimes my tests fail due to the asserts being run before the response comes back here in my integration tests:
it('should find all countries when no id is specified', co.wrap(function *(){
var uri = '/countries';
var response = yield request.get(uri);
should.exist(response.body);
response.status.should.equal(200);
}));
Not sure how to tweak mocha or supertest to wait or if I should use a promise here or what. I'm using generators with mocha here.
Adding a longer timeout to mocha does absolutely nothing. The query behind this particular test takes a bit longer than my other tests. My other tests run just fine.
Related
I wonder if there is any way to prevent tests from running when we have an error.
For example, in the beforeAll() function. I have tried "return" or "throw" an error but after that, Jest runs all of my tests.
So when my code in the beforeAll() function has an error that can affect other test results, I would like to be able to prevent Jest from running all the tests.
Jest tries to run all the tests even though we already know all the tests would fail.
You can try to use bail in config:
bail: 2 // finish after 2 failed tests
or
bail: true // finish after first
https://jestjs.io/docs/cli#--bail
To fail your test use:
fail('something wrong');
Is it possible to run Mocha programmatically, yet run it in a "verbose" mode and use the results programmatically?
Right now I am using it in NodeJS via mocha modules (using chai internally in the suite for the assertions).
What I want is to get more data about the failed tests than the generic errors of style: "expected true and got false".
Is there for instance a way to check which assertion failed and why, in case of multiple assertions within a test, or receive more information about a specific test, and if yes, how?
When you run Mocha programmatically, the mocha.run() method returns a Runner object. If you listen to fail events, you'll be able to learn of all test failures. Here's an example adapted from the page I linked to above:
var Mocha = require('mocha');
var fs = require('fs');
var path = require('path');
var mocha = new Mocha();
var testDir = '.'
fs.readdirSync(testDir).filter(function(file){
// This gets all files that end with the string test.js (so
// footest.js, bar_test.js, baz.test.js, etc.
return file.substr(-7) === 'test.js';
}).forEach(function(file){
mocha.addFile(path.join(testDir, file));
});
var runner = mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures);
});
});
// This is how we get results.
runner.on('fail', function(test, err){
console.log(err);
});
Is there for instance a way to check which assertion failed and why, in case of multiple assertions within a test, or receive more information about a specific test, and if yes, how?
Mocha does not provide any facility to relate the exception you get through err in the fail handler to a specific assertion. This is due to the fact that Mocha is designed to be used with whatever assertion library you want. It only detects that an assertion has failed when it catches the exception raised by the failing assertion. It does not know anything about the assertions that were successful or the assertions that were not executed because the test ended early on the failing assertion. You may be able to reverse engineer something from the stack trace but Mocha won't help you towards this goal.
Here I am attaching my code, I am passing done callback and using supertest for request. Since I am using assert/expect in my testcase inside request.end block why I need to worry about timeout? What is mistake I am making here.
it('should get battle results ', function(done) {
request(url)
.post('/compare?vf_id='+vf_id)
.set('access_token',access_token)
.send(battleInstance)
.end(function(err, res){ // why need timeout
if (err) return done(err);
console.log(JSON.stringify(res.body));
expect(res.body.status).to.deep.equal('SUCCESS');
done();
});
});
Testcase results following response:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
If I am running my testcases with mocha command then its show this error while If I am running test mocha --timeout 15000 then testcase is passing correctly. But I want to avoid timeout, How can I do that?
If I am running my testcases with mocha command then its show this error while If I am running test mocha --timeout 15000 then testcase is passing correctly. But I want to avoid timeout, How can I do that?
You can't avoid timeouts, since it looks like you're testing a remote service. If, for whatever reason, the request to that service takes a long time, you will run into timeouts.
You can tell Mocha to disable for timeout checking by setting the timeout to 0, but that's probably also not ideal because it may cause each test case to take an excessive amount of time.
As an alternative, you can mock request (which I assume is superagent) so you can control the entire HTTP request/response flow, but since it looks like you're testing a remote service (one which you have no control over) that would make this particular test case moot.
In mocha a default timeout of 2 seconds (2000ms) is set by default.
You can extend the default (global) timeout from the command line using the --timeout xxxx flag.
If you want instead to change the timeout for a specific test case you can use the this.timeout( xxxx ) function - note it does not work for arrow functions - (where xxxx is a number like 20000 representing milliseconds).
it('My test', function(){
this.timeout(5000);
//... rest of your code
});
You can also set a timeout of a set of test cases (wrapped by a describe):
describe("My suite", function(){
// this will apply for both "it" tests
this.timeout(5000);
it( "Test 1", function(){
...
});
it( "Test 2", function(){
...
});
});
It also works for before, beforeEach, after, afterEach blocks.
More documentation is available here: https://mochajs.org/#timeouts
Consider that 2 seconds is usually a good amount of time to run your tests so I would say that extend the default timeout should be an exception, not the common rule in your tests.
Also if your test is not async and you have to extend the timeout I would strongly suggest to review the function that is taking so long before extending the timeout.
Mocha : Timeouts
Test-specific timeouts may also be applied, or the use of this.timeout(0) to disable timeouts all together:
To disable the timeout from happening simply set it to 0. I use mocha <file> --timeout 0 when I'm debugging so the timeout error does not get thrown.
Here is what you need
mocha timeouts
describe('a suite of tests', function() {
this.timeout(500);
it('should take less than 500ms', function(done){
setTimeout(done, 300);
});
it('should take less than 500ms as well', function(done){
setTimeout(done, 250);
});
})
How do I force a Mochajs test to end completely without continuing on to the next tests. A scenario could be prevent any further tests if the environment was accidentally set to production and I need to prevent the tests from continuing.
I've tried throwing Errors but those don't stop the entire test because it's running asynchronously.
The kind of "test" you are talking about --- namely checking whether the environment is properly set for the test suite to run --- should be done in a before hook. (Or perhaps in a beforeEach hook but before seems more appropriate to do what you are describing.)
However, it would be better to use this before hook to set an isolated environment to run your test suite with. It would take the form:
describe("suite", function () {
before(function () {
// Set the environment for testing here.
// e.g. Connect to a test database, etc.
});
it("blah", ...
});
If there is some overriding reason that makes it so that you cannot create a test environment with a hook and you must perform a check instead you could do it like this:
describe("suite", function () {
before(function () {
if (production_environment)
throw new Error("production environment! Aborting!");
});
it("blah", ...
});
A failure in the before hook will prevent the execution of any callbacks given to it. At most, Mocha will perform the after hook (if you specify one) to perform cleanup after the failure.
Note that whether the before hook is asynchronous or not does not matter. (Nor does it matter whether your tests are asynchronous.) If you write it correctly (and call done when you are done, if it is asynchronous), Mocha will detect that an error occurred in the hook and won't execute tests.
And the fact that Mocha continues testing after you have a failure in a test (in a callback to it) is not dependent on whether the tests are asynchronous. Mocha does not interpret a failure of a test as a reason to stop the whole suite. It will continue trying to execute tests even if an earlier test has failed. (As I said above, a failure in a hook is a different matter.)
I generally agree with Glen, but since you have a decent use case, you should be able to trigger node to exit with the process.exit() command. See http://nodejs.org/api/process.html#process_process_exit_code. You can use it like so:
process.exit(1);
As of the mocha documentation, you can add --exit flag when you are executing the tests.
It will stop the execution whenever all the tests have been executed successfully or not.
ex:
mocha **/*.spec.js --exit
Am using Mocha, Chai, Sinon, Proxyquire and Nock.
For this particular test scenario (for which this question is being asked), wish to test the exact same URL several times, each in a separate test that expects a different response.
For example, a response with no merchant feeds, 1 merchant feed, and yet again with 2 merchant feeds.
The existing code all works, furthermore if I run tests individually they pass.
However, if i run them together using Mocha in a single suite they fail. Believe the issue is that Nock hijacks the global http object for a given URL and each test (running asynchronously at the same time) is competing for the same global response reference.
In the scenario above, a response prepared with a canned reply of 1 merchant is getting say overwritten by the setup to respond with 2 merchants etc.
Is there a mechanism to avoid this happening, for instance guarantees around serial execution of async Mocha testcases (which I believed was the default behaviour).
In response to your point 2), you can use nock.cleanAll() to cleanup all prepared nocks:
https://github.com/pgte/nock#cleanall
You can put this in an afterEach block to make sure you don't have leftover nocks between tests.
afterEach ->
nock.cleanAll()
Ok, so this works (sample code):
beforeEach(function (done) {
nock(apiUrl)
.get('/dfm/api/v1/feeds?all=false')
.reply(200, [
{'merchantId': 2, 'id': 2, 'disabled': false}
], { server: 'Apache-Coyote/1.1',
'set-cookie': [ 'JSESSIONID=513B77F04A3A3FCA7B0AE1E99B57F237; Path=/dfm/; HttpOnly' ],
'content-type': 'application/json;charset=UTF-8',
'transfer-encoding': 'chunked',
date: 'Thu, 03 Jul 2014 08:46:53 GMT' });
batchProcess = proxyquire('./batchProcess', {
'./errorHandler': errorHandler.stub,
'./batchTask': batchTask.stub
});
winston.info('single valid feed beforeEach completed');
done();
});
There were lots of complicating factors. Two things to be aware of:
1). I had async testcases but was using beforeEach() without the done param. This was then causing the URL collisions. By explcitly declaring each beforeEach(done) and invoking done() Mocha will run in serial order and there is no longer an issue.
2). Be sure that if you have more than one test in same testsuite file, that any Nock fixtures you set in a previous test actually get executed IF you have declared the same URL in a subsequent test with alternate response. If the prior nock fixture doesn't get invoked then nock STILL retains the response from the wrong test (the previous one). This was my primary problem. You could argue that tests should not have any fixtures declared if they don't get run - but you could also argue this is still a bug in the way Nock works. The test fixtures were each isolated in their own describe / beforeEach(done) functions..
Update 2 days later... OK point 2). just bit me again, and I was pleased I wrote the note above to remind myself about this hard to debug issue. If you are using Mocha and Nock together be aware of this issue!!
Did eventually implement a nock helper function too, to assist with this (coffeescript here):
global.resetNock = ->
global.nock.cleanAll()
global.nock.disableNetConnect()
Then at the start of beforeEach just apply resetNock()