Reputation: 33391
Observe the following tests:
describe("Testing i", function(){
var i = 0;
it('i should be 0', function() {
expect(i).to.equal(0);
});
i++;
it('i should be 1', function() {
expect(i).to.equal(1);
});
i= 7;
it('i should be 7', function() {
expect(i).to.equal(7);
});
});
The first two tests fail. But I have no idea why! What am I doing wrong?
The test shows the following:
I'm porting QUnit to Mocha and I'm looking where the asserts should go.
In QUnit you have Module -> Test -> Asserts.
Is it here Describe -> Describe -> It's?
Upvotes: 2
Views: 1397
Reputation: 14750
A Solution like on the Mocha Documentation https://mochajs.org/
describe("Testing i", function(){
var i;
it('i should be 0', function() {
i = 0;
expect(i).to.equal(0);
});
it('i should be 1', function() {
i++;
expect(i).to.equal(1);
});
it('i should be 7', function() {
i= 7;
expect(i).to.equal(7);
});
});
The calling order, as asked in the Question
I tested it with a adapted code from this article http://cwinters.com/2014/09/26/mocha-nested-hook-ordering.html
Here is the code, I used
'use strict';
describe('level 1', function() {
before(function() { console.log("L1 - before") });
beforeEach(function() { console.log("L1 - beforeEach") });
after(function() { console.log("L1 - after") });
afterEach(function() { console.log("L1 - afterEach") });
console.log("inner DESCRIBE BEFORE L1A") // equivalent to asigning the variable the first time
it('L1 test A', function() {});
console.log("inner DESCRIBE BEFORE L1B") // equivalent to asigning the variable the second time
it('L1 test B', function() {});
describe('level 2', function() {
before(function() { console.log("L2 - before") });
beforeEach(function() { console.log("L2 - beforeEach") });
after(function() { console.log("L2 - after") });
afterEach(function() { console.log("L2 - afterEach") });
it('L2 test A', function() {});
it('L2 test B', function() {});
});
});
here the result
inner DESCRIBE BEFORE L1A // execute First
inner DESCRIBE BEFORE L1B // execute Second
level 1 // now the test are executed
L1 - before
L1 - beforeEach
√ L1 test A
L1 - afterEach
L1 - beforeEach
√ L1 test B
L1 - afterEach
level 2
L2 - before
L1 - beforeEach
L2 - beforeEach
√ L2 test A
L2 - afterEach
L1 - afterEach
L1 - beforeEach
L2 - beforeEach
√ L2 test B
L2 - afterEach
L1 - afterEach
L2 - after
L1 - after
4 passing (64ms)
=> The describe
Block will be execute immediately, so multiple variable asignment to the same varible will be overriden by the last one, before any other function is called.
The first two test Fail because i==7
when all three tests are executed.
If the sequence is really needed you could use closure , but this would add a lot more complexity.
Upvotes: 1
Reputation: 33391
Looks like the following is the way to go:
describe("Testing i", function(){
it('i increments', function(){
var i = 0;
expect(i, 'i should be 0').to.equal(0);
i++;
expect(i, 'i should be 1').to.equal(1);
i = 7;
expect(i, 'i should be 7').to.equal(7);
});
});
The QUnit.module
maps to describe
, QUnit.test
maps to it
and assert
maps to expect
.
I've written a blog on the subject: Convert QUnit test to Mocha / Chai.
Upvotes: 0
Reputation: 1135
Answering to question, how the execution flow works. Mocha starts with describe block.
In describe block first of all it executes all the code that is not in the it
block.
So in your code first of all these 3 statements are executed before executing it
blocks
var i = 0;
i++;
i=7;
Last value assigned to i is 7. Now it will start executing it blocks.
Upvotes: 2
Reputation: 113916
You're doing the tests wrong. The entire test, variable setup and all, MUST BE INSIDE the it
functions.
What the it
functions do is just push your tests to a list that will be executed either by the describe
function or by mocha itself. The it
functions do NOT execute the tests.
The correct way to write your test is as follows:
describe("Testing i", function(){
it('i should be 0', function() {
var i = 0;
expect(i).to.equal(0);
});
it('i should be 1', function() {
var i = 0;
i++;
expect(i).to.equal(1);
});
it('i should be 7', function() {
var i = 0;
i = 7;
expect(i).to.equal(7);
});
});
FWIW. All tests are executed synchronously unless you pass an argument into the callback of the it
function. It's just that they're not executed inside the describe
function. The it
functions just compiles all your it
calls into a list of tests.
Therefore, if you need to do a series of operations you can do this:
describe("Testing i", function(){
var i;
it('i should be 0', function() {
i = 0;
expect(i).to.equal(0);
});
it('i should be 1', function() {
i++;
expect(i).to.equal(1);
});
it('i should be 7', function() {
i = 7;
expect(i).to.equal(7);
});
});
Note however that this is not recommended because if the first test fails then some of the following tests may fail as well. In this example, if the first test fails because the value of i
is not 0 the second test will fail too. However, this pattern may be useful for steps that take a long time to execute (website login for example).
This allows mocha to do fancy test reporting like progress bars etc. Without knowing how many tests there are to run (a test is an it
function), mocha cannot know what percentage to draw the progress bar.
It also allows mocha to do fancy formatting of error messages. If you've used mocha, you'll notice that mocha collects all error messages (fails) and print them at the end. To do that what mocha does is execute the tests (it
functions) one at a time in a controlled manner and collecting any errors thrown. That's not possible if you rely on javascript syntax alone unless you hack the interpreter in C. But you can do that if you have a list of functions inside an array and execute them one function at a time.
Upvotes: 2