I'm trying to learn Mocha and am having trouble dealing with asynchronous code.
I would like to create a test database, populate it with some data, and then write some tests. My issue is that I can not figure out how to require that my test database be created and populated before additional tests are run. Here's the basic structure of my code:
describe('Database', function() {
// create the DB and populate it with some test data
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
// tests below here
});
From reading the documentation, it seems that I need to use before to ensure that my asynchronous code runs prior to my tests. To attempt this, I tried using something like this:
describe('Database', function() {
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data);
});
done();
});
// tests below here
});
How can I tell Mocha to first create and populate my database before running subsequent tests?
Using before() is the right solution, just invoke done() when all your data has finished writing. Something like this:
before(function(done) {
iniDB(dbName, function(db) {
addDataToDB(db, table, data, function() {
done();
});
});
});
Related
I'm writing test cases with mocha in Nodejs and want to reset database data before running the tests. I'm using Knex as query builder for executing queries.
I wrote following logic:
describe('Activities:', function() {
before(funtion(){
activityDBOperations.deleteAll()
.then(function(){
// all records are deleted
});
});
it('it should add a record into Activities table: multiple time activity', function(done) {
activityDBOperations.addRecord(requestParams)
.then(function(data) {
expect(data.length > 0).to.equal(true);
done();
});
});
});
The problem is that test cases start executing and not waiting for deleteAll operation to finish. What I understand is since deleteAll is returning promise, the program execution move forward because of asynchronous nature of promises.
How can I make sure that test cases should run only when deleteAll has finished?
Either provide a callback to your before hook and call it in then:
before(function(done) {
activityDBOperations.deleteAll()
.then(function() {
// all records are deleted
done();
});
});
or, according to Mocha docs, just return a promise from before:
before(function() {
return activityDBOperations.deleteAll();
});
Add return statements so the Promises are actually returned.
I am building an app using the MEAN stack and Webdriver for testing.
At the moment I am cleaning the database between tests by using Mocha's beforeEach and afterEach hooks, e.g.:
describe('Links', function() {
// drop DB collections
beforeEach(function(done){
//create database objects
});
afterEach(function(done){
// drop DB collections
});
});
Is there a way of setting up wdio.conf.js for this to happen before and after each of my tests automatically? The config's before: and after: function() {} run as a beforeAll / afterAll rather than for each test.
Yes, see this url: http://webdriver.io/guide/testrunner/gettingstarted.html
if you launch the wdio config, will generate a file named wdio.conf.js, on this file exists functions to launch scripts after or before the tests, i show the example of the functions contains this file:
// =====
// Hooks
// =====
// Run functions before or after the test. If one of them returns with a promise, WebdriverIO
// will wait until that promise got resolved to continue.
//
// Gets executed before all workers get launched.
onPrepare: function() {
// do something
},
//
// Gets executed before test execution begins. At this point you will have access to all global
// variables like `browser`. It is the perfect place to define custom commands.
before: function() {
// do something
},
//
// Gets executed after all tests are done. You still have access to all global variables from
// the test.
after: function(failures, pid) {
// do something
},
//
// Gets executed after all workers got shut down and the process is about to exit. It is not
// possible to defer the end of the process using a promise.
onComplete: function() {
// do something
}
Is important, if you launch a script asynchronous, and you wait the callback in the moment of clean the database so you need a promise, else the next step hook will launch not waiting the previous function hook, example:
onPrepare: function() {
return new Promise(function(resolve, reject) {
sauceConnectLauncher({
username: 'the_pianist2',
accessKey: '67224e83a-1cf7440d-8c88-857c4d3cde49',
}, function (err, sauceConnectProcess) {
if (err) {
return reject(err);
}
console.log('success');
resolve();
});
});
},
I am trying to prototype a load testing scenario on socket interactions using Mocha and should.js. I have an array of user details which I want to authenticate using socket communication and wish to verify their responses. It works fine for a single user, however when I try to loop for multiple users - I end up with issues. Had gathered some inputs based on the post:Tests from looping through async JavaScript (Mocha) .
Below is the code snippet:
var users = [{name:'A',password:'password',expected:'success'},{name:'B',password:'badPass',expected:'failure'}];
describe('socket Interaction test' , function() {
function socketInteraction(users, done) {
client.emit('userAuthentication', {'name':users.name,'password':users.password}, function(callback) {
console.log('Emit' + users.name);
});
client.on('userAuthenticationResponse', function(response) {
console.log('Resp' + response.status + 'Expected' + users.expected);
response.status.should.equal(users.expected);
done();
});
}
it('Dummy', function(done) {
describe('Mutiple login Test Async', function() {
it('User Login Test', function(done) {
users.forEach(function(users, callback) {
console.log(users.name);
socketInteraction(users, function(err) {
if (err) {
return;
}
done();
});
});
});
});
});
});
The response I get upon running the test is:
socket Interaction test
✓ Dummy
Mutiple login Test Async
A
B
RespsuccessExpectedsuccess
✓ User Login Test
RespsuccessExpectedfailure
2 passing (43ms)
The second test has to fail. Not sure where I have messed up the code. Appreciate some pointers to fix this. Thanks.
The done Parma should be called in the second param of the async.forEach. The done you call in the loop function should be callback(), to tell async that just that user is finished.
You don't have the async finished callback yet at all.
Would have posted code but am on my phone. I can add later if it's not clear.
I'm working with mongojs and writing tests for mocha running coverage with istanbul. My issue is that I would like to include testing db errors.
var mongojs = require('mongojs');
var db = mongojs.connect(/* connection string */);
var collection = db.collection('test');
...
rpc.register('calendar.create', function(/*... */) {
collection.update({...}, {...}, function (err, data) {
if (err) {
// this code should be tested
return;
}
// all is good, this is usually covered
});
});
the test looks like this
it("should gracefully fail", function (done) {
/* trigger db error by some means here */
invoke("calendar.create", function (err, data) {
if (err) {
// check that the error is what we expect
return done();
}
done(new Error('No expected error in db command.'));
});
});
There is a fairly complex setup script that sets up the integration testing environment. The current solution is to disconnect the database using db.close() and run the test resulting in an error as wanted. The problem with this solution arises when all the other tests after that require the database connection fail, as I try to reconnect without success.
Any ideas on how to solve this neatly? Preferably without writing custom errors that might not be raised by next version of mongojs. Or is there a better way of structuring the tests?
What about mocking the library that deals with mongo?
For example, assuming db.update is eventually the function that gets called by collection.update you might want to do something like
describe('error handling', function() {
beforeEach(function() {
sinon.stub(db, 'update').yields('error');
});
afterEach(function() {
// db.update will just error for the scope of this test
db.update.restore();
});
it('is handled correctly', function() {
// 1) call your function
// 2) expect that the error is logged, dealt with or
// whatever is appropriate for your domain here
});
});
I've used Sinon which is
Standalone test spies, stubs and mocks for JavaScript. No dependencies, works with any unit testing framework.
Does this make sense?
I have been trying to test my test server using mocha. This is the following code that I use, almost the same as one found in another similar post.
beforeEach(function(done) {
// Setup
console.log('test before function');
ws.on('open', function() {
console.log('worked...');
done();
});
ws.on('close', function() {
console.log('disconnected...');
});
});
afterEach(function(done) {
// Cleanup
if(readyState) {
console.log('disconnecting...');
ws.close();
} else {
// There will not be a connection unless you have done() in beforeEach, socket.on('connect'...)
console.log('no connection to break...');
}
done();
});
describe('WebSocket test', function() {
//assert.equal(response.result, null, 'Successful Authentification');
});
the problem is that when I execute this draft, none of the console.log that is expected to be seen is visible on the command prompt. Can you please explain to me what am I doing wrong?
Georgi is correct that you need an it call to specify a test but you don't need to have a top level describe in your file if you don't want to. You could replace your single describe with a bunch of it calls:
it("first", function () {
// Whatever test.
});
it("second", function () {
// Whatever other test.
});
This works very well if your test suite is small and composed of only one file.
If your test suite is bigger or spread among multiple files, I would very strongly suggest you put your beforeEach and afterEach together with your it inside the describe, unless you are absolutely positive that every single test in the suite needs the work done by beforeEach or afterEach. (I've written multiple test suites with Mocha and I've never had a beforeEach or afterEach that I needed to run for every single test.) Something like:
describe('WebSocket test', function() {
beforeEach(function(done) {
// ...
});
afterEach(function(done) {
// ...
});
it('response should be null', function() {
assert.equal(response.result, null, 'Successful Authentification');
});
});
If you do not put your beforeEach and afterEach inside describe like this, then let's say you have one file to test web sockets and another file to test some database operations. The tests in the file that contains the database operation tests will also have your beforeEach and afterEach executed before and after them. Putting the beforeEach and afterEach inside the describe like shown above will ensure that they are performed only for your web socket tests.
You have no tests in your example. If there are no tests to be run, then before and after hooks won't be invoked. Try adding a test like:
describe('WebSocket test', function() {
it('should run test and invoke hooks', function(done) {
assert.equal(1,1);
done();
});
});
You need to have a test-callback(eg. it) inside suite-callback(eg, describe) to execute beforeEach() and afterEach() hooks. More info https://mochajs.org/#run-cycle-overview