Let me start by saying I am quite new to node.js and mocha.It just breaks my head. I started using the tdd approach and I am trying to get the test that will start or has just finished from within the beforeEach and afterEach functions, but I've had no luck.(I am mostly interested in afterEach). At least I couldn't figure a neat way of doing it. The only thing I could think of was keeping the tests and the suite in a variable and then on afterEach() just do some matching to see which test has finished.
Ideally where it says 'test name' I want to have something like suite.test.name
suite('my test suite', function() {
beforeEach(function () {
console.log('test name');
});
test('first test', function (done) {
var testarray = ['1', '3', '5', '7'];
testarray.forEach(function(num, index) {
console.log('num: ' + num + ' index: ' + index);
},
done());
});
afterEach(){
console.log('test name');
}
}
You get the name of the current test with this.currentTest.title
afterEach(function(){
console.log(this.currentTest.title)
})
I find that i use this.currentTest.fullTitle() more than this.currentTest.title-- i prefer to have the describe names as well.
If you have nested describe blocks and for some reason you want to separate the title portions you can do something like the following in either the beforeEach or afterEach methods:
function titles(test) {
console.log(test.title)
if (test.parent) {
titles(test.parent)
}
}
titles(this.currentTest)
Related
I want to stop a whole describe of JEST without throwing an error or stoping the other describes.
Im writing e2e test for my app with JEST and PUPPETEER, I write the test in a way every DESCRIBE its a flow of the path and every IT its a step, inside a IT I want to stop the flow if the pages dont match some conditions.
describe('Book a Room', ()=> {
it ('enter on main page' async() => await mainPage.navigateToMainPage())
it('go to book room page', async() => await bookRoomPage.navigateToBookRoomPage())
// The function its inside the "bookRoomPage"
it('check if the user can book room', () => {
if (!page.userCanOpenARoom()) {
// DONT EXECUTE THE NEXT IT BUT CONTINUE WITH THE OTHER DESCRIBE
}
})
it('go to book preview...', async() => bookRoomPreviewPage.navigateToBookRoomPreviewPage());
// REMAINING FLOW
})
I already try with process.exit(0) but exit the whole process
You can try out what this blog says here its for sharing specs in your test suites which is pretty handy. But for your case specifically you could extract your page cases in separate suites and then dynamically include the test case on runtime if a condition is met.
Something like:
Include Spec function shared_specs/index.js
const includeSpec = (sharedExampleName, args) => {
require(`./${sharedExampleName}`)(args);
};
exports.includeSpec = includeSpec;
Test A shared_specs/test_a.js
describe('some_page', () => {
it...
})
Test B shared_specs/test_b.js
describe('some_other_page', () => {
it...
})
and then in your test case
// Something like this would be your path I guess
import {includeSpec} from '../shared_specs/includeSpec.js'
describe('Book a Room', async ()=> {
if (page.userCanOpenARoom()) {
includeSpec('test_a', page);
} else {
includeSpec('test_b', page); // Or dont do anything
}
});
Just make sure that you check the paths since
require(`./${sharedExampleName}`)(args);
will load it dynamically at runtime, and use includeSpec in your describe blocks not it blocks. You should be able to split up your test suites pretty nicely with this.
I try to call a lot of async functions in my mocha JS before hook but they are executed at last. Basically I am trying to execute repeated tests with different params from the constructor initialization.
I tried with only one function but it also execute at last.Tried to pass done() function to inner async function but it doesnt help either.
a.test.js and base.tests.js files :
describe('Test block', () => {
before((done) => {
const baseClass = new baseClass()
baseTests.applyTests(done)
});
describe('test',()=>{
....first which should be executed;
})
}
----------------------------------------------------------------
class baseClass {
constructor() {
init smth....
}
async applyTests(done) {
await Promise.All(
[
a(),
b(),
c()
]
done();
)
}
async a() {
return describe('TEST', () => {
it('TEST', (done) => {
chai.request(server)
.get(url)
.end((err, res) => {
asserts...
done();
});
});
}}
I expect to run first the async operations in the before hook and after that all other tests.
Keep in mind that describe and it blocks do not execute any tests; they add tests to the test list that Mocha will execute. Putting a describe block inside a function called from a before hook like this won't ever end up executing code like chai.request(... etc. (And even if it did, it would be totally broken: a before hook is run before each test, you don't want to do asserts there because it won't be linked to any particular unit test.)
I can't give more concrete advice because I'm not sure what you were trying to accomplish, but in general, your describe and it blocks should be top-level constructs and not put inside other code like this.
EDIT: Just to make the execution path here clear: your before hook runs, which calls applyTests, which calls a(), which executes a describe block and adds your unit test TEST to the test list, then it returns. It then begins running tests, including test and TEST.
EDIT: Ah, makes sense, let me suggest two patterns that are often used in unit tests.
Pattern 1: "Test Loop"
This pattern creates many similar-looking tests, using an array of input params to produce appropriate test descriptions and test bodies.
[
{ foo: "milk", bar: "smoothie" },
{ foo: "yogurt", bar: "fridge" },
{ foo: "whatever", bar: "container" }
].forEach(test => {
it("puts the " + test.foo + " in the " + test.bar, function () {
assert(subject.someMethod(foo) === bar);
});
});
Pattern 2: "Test Helper"
This pattern creates individual tests, but puts a common test body in a helper method so it can be reused.
function testSomeMethod(foo, bar) {
assert(subject(foo) == "bar");
}
it("puts the milk in the fridge", function () {
testSomeMethod("milk", "fridge");
});
it("puts the cereal in the pantry", function () {
testSomeMethod("cereal", "pantry");
});
Examples above are very simple, but either the test loop or the test helper pattern can be used to encapsulate a much more complicated series of steps (set up a request, look at some response headers / bodies, etc.).
I'm trying to create mocha tests for my controllers using a config that has to be loaded async. Below is my code. However, when the mocha test is run, it doesn't run any tests, displaying 0 passing. The console.logs are never even called. I tried doing before(next => config.build().then(next)) inside of the describe, but even though the tests run, before is never called. Is there a way to have the config be loaded one time before any tests are run?
'use strict';
const common = require('./common');
const config = require('../config');
config
.build()
.then(test);
function test() {
console.log(1);
describe('Unit Testing', () => {
console.log(2);
require('./auth');
});
}
You should run Mocha with the --delay option, and then use run() once you are done building your test suite. Here is an example derived from the code you show in the question:
'use strict';
function test() {
console.log(1);
describe('Unit Testing', () => {
console.log(2);
it("test", () => {
console.log(3);
});
});
// You must use --delay for `run()` to be available to you.
run();
}
setTimeout(test, 1000);
I'm using setTimeout to simulate an asynchronous operation. Using --delay and run() allows you to build a suite that is the result of an asynchronous computation. Note, however, that the suite must be built in one shot. (You cannot have an asynchronous process inside describe that will make calls to it. This won't work.)
One thing you should definitely not do is what rob3c suggests: calling describe or it (or both) from inside a hook. This is a mistake that every now and then people make so it is worth addressing in details. The problem is that it is just not supported by Mocha, and therefore there are no established semantics associated with calling describe or it from inside a hook. Oh, it is possible to write simple examples that work as one might expect but:
When the suite becomes more complex, the suite's behavior no longer corresponds to anything sensible.
Since there are no semantics associated with this approach, newer Mocha releases may handle the erroneous usage differently and break your suite.
Consider this simple example:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]);
describe("top", () => {
let flag;
before(() => {
flag = true;
return p.then((names) => {
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
});
});
after(() => {
flag = false;
});
it("regular test", () => {
assert(flag);
});
});
When we run it, we get:
top
✓ regular test
embedded
1) foo
2) bar
3) baz
1 passing (32ms)
3 failing
// [stack traces omitted for brevity]
What's going on here? Shouldn't all the tests pass? We set flag to true in the before hook for the top describe. All tests we create in it should see flag as true, no? The clue is in the output above: when we create tests inside a hook, Mocha will put the tests somewhere but it may not be in a location that reflects the structure of the describe blocks in the code. What happens in this case is that Mocha just appends the tests created in the hook the the very end of the suite, outside the top describe, so the after hook runs before the dynamically created tests, and we get a counter-intuitive result.
Using --delay and run(), we can write a suite that behaves in a way concordant with intuition:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]).then((names) => {
describe("top", () => {
let flag;
before(() => {
flag = true;
});
after(() => {
flag = false;
});
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
it("regular test", () => {
assert(flag);
});
});
run();
});
Output:
top
✓ regular test
embedded
✓ foo
✓ bar
✓ baz
4 passing (19ms)
In modern environments, you can use top-level await to fetch your data up front. This is a documented approach for mocha: https://mochajs.org/#dynamically-generating-tests
Slightly adapting the example from the mocha docs to show the general idea:
function fetchData() {
return new Promise((resolve) => setTimeout(resolve, 5000, [1, 2, 3]));
}
// top-level await: Node >= v14.8.0 with ESM test file
const data = await fetchData();
describe("dynamic tests", function () {
data.forEach((value) => {
it(`can use async data: ${value}`, function () {
// do something with data here
});
});
});
This is nice as it is on a per-file basis, and doesn't involve you taking on management responsibility of the test runner as you do with --delay.
The problem with using the --delay command line flag and run() callback that #Louis mentioned in his accepted answer, is that run() is a single global hook that delays the root test suite. Therefore, you have to build them all at once (as he mentioned), which can make organizing tests a hassle (to say the least).
However, I prefer to avoid magic flags whenever possible, and I certainly don't want to have to manage my entire test suite in a single global run() callback. Fortunately, there's a way to dynamically create the tests on a per-file basis, and it doesn't require any special flags, either :-)
To dynamically create It() tests in any test source file using data obtained asynchronously, you can (ab)use the before() hook with a placeholder It() test to ensure mocha waits until before() is run. Here's the example from my answer to a related question, for convenience:
before(function () {
console.log('Let the abuse begin...');
return promiseFn().
then(function (testSuite) {
describe('here are some dynamic It() tests', function () {
testSuite.specs.forEach(function (spec) {
it(spec.description, function () {
var actualResult = runMyTest(spec);
assert.equal(actualResult, spec.expectedResult);
});
});
});
});
});
it('This is a required placeholder to allow before() to work', function () {
console.log('Mocha should not require this hack IMHO');
});
I want to compute some values before some tests. what is the best way to do that? To use "before" or call functions?
// Way 1
var expect = require('chai').expect;
describe("a test", function() {
var val1, val2;
before(function() {
val1 = computeVal1();
});
it("should return hi1", function() {
expect(val1).to.equal('hi1');
});
before(function() {
val2 = computeVal2();
});
it("should return hi2", function() {
expect(val2).to.equal('hi2');
});
});
Is the above way is better or the below way is better?
// Way 2
var expect = require('chai').expect;
describe("a test", function() {
var val1, val2;
val1 = computeVal1();
it("should return hi1", function() {
expect(val1).to.equal('hi1');
});
val2 = computeVal2();
it("should return hi2", function() {
expect(val2).to.equal('hi2');
});
});
It really makes no difference in this case because ultimately in the second example computeVal1() will run before the tests do. However, given this is exactly what the before / beforeEach hooks were designed for, I would be inclined to stay consistent with the framework and use them.
This is from the mocha documentation:
describe('hooks', function() {
before(function() {
// runs before all tests in this block
})
after(function(){
// runs after all tests in this block
})
beforeEach(function(){
// runs before each test in this block
})
afterEach(function(){
// runs after each test in this block
})
// test cases
})
So, there is not much difference in using before or calling functions directly under the describe. In your second example, val2's value won't be available to the first test, but in the first example, val2's value will be.
However, it is better practice IMO, to use beforeEach. This way state from one test does not affect another test.
Using the hooks (before and beforeEach) to initialize the data that your test uses is usually the best thing to do. Consider this:
In your 2nd snippet, if computeVal1 or computeVal2 fail, then Mocha won't run any test whatsoever. In the 1st snippet, Mocha may run some tests before it tries to call them and they fail. If you have many test files that Mocha loads, it may matter to you that Mocha runs as many test as it can before a failure occurs.
In your 2nd snippet, Mocha will almost always run computeVal1 and computeVal2 even if they are not needed. If they are computationally costly, you'll pay this cost every time. If you run mocha --grep=foo so that it does not select any of your tests, both functions will be called.
In your first snippet, Mocha will run them only if they are needed. If you run mocha --grep=foo, Mocha won't call your functions.
In your 2nd snippet, even using describe.skip for your describe call won't make Mocha skip calling the functions.
The documentation at the official Mocha site contains this example:
describe('User', function(){
describe('#save()', function(){
it('should save without error', function(done){
var user = new User('Luna');
user.save(function(err){
if (err) throw err;
done();
});
})
})
})
I want to know when I should nest my tests in the describe function and what the basic purpose of describe is. Can I compare the first argument passed to describe to comments in a programming language? Nothing is shown of describe in the output on the console. Is it only for readability purposes, or there is some other use for this function?
Is there anything wrong if I use it like this?
describe('User', function(){
describe('#save()', function(){
var user = new User('Luna');
user.save(function(err){
if (err) throw err;
done();
})
})
})
If I do it this way, the test still passes.
The it call identifies each individual tests but by itself it does not tell Mocha anything about how your test suite is structured. How you use the describe call is what gives structure to your test suite. Here are some of the things that using describe to structure your test suite does for you. Here's an example of a test suite, simplified for the purpose of discussion:
function Foo() {
}
describe("Foo", function () {
var foo;
beforeEach(function () {
foo = new Foo();
});
describe("#clone", function () {
beforeEach(function () {
// Some other hook
});
it("clones the object", function () {
});
});
describe("#equals", function () {
it("returns true when the object passed is the same", function () {
});
it("returns false, when...", function () {
});
});
afterEach(function () {
// Destroy the foo that was created.
// foo.destroy();
});
});
function Bar() {
}
describe("Bar", function () {
describe("#clone", function () {
it("clones the object", function () {
});
});
});
Imagine that Foo and Bar are full-fledged classes. Foo has clone and equals methods. Bar has clone. The structure I have above is one possible way to structure tests for these classes.
(The # notation is used by some systems (like for instance, jsdoc) to indicate an instance field. So when used with a method name, it indicates a method called on an instance of the class (rather than a class method, which is called on the class itself). The test suite would run just as well without the presence of #.)
Provide Banners
Some of Mocha's reporters show the names you give to describe in the reports they produce. For instance, the spec reporter (which you can use by running $ mocha -R spec), would report:
Foo
#clone
✓ clones the object
#equals
✓ returns true when the object passed is the same
✓ returns false, when...
Bar
#clone
✓ clones the object
4 passing (4ms)
Help Select Parts to Run
If you want to run only some of the tests, you can use the --grep option. So if you care only about the Bar class, you can do $ mocha -R spec --grep Bar, and get the output:
Bar
#clone
✓ clones the object
1 passing (4ms)
Or if you care only about the clone methods of all classes, then $ mocha -R spec --grep '\bclone\b' and get the output:
Foo
#clone
✓ clones the object
Bar
#clone
✓ clones the object
2 passing (5ms)
The value given to --grep is interpreted as a regex so when I pass \bclone\b I'm asking only for the word clone, and not things like clones or cloned.
Provide Hooks
In the example above the beforeEach and afterEach calls are hooks. Each hook affects the it calls that are inside the describe call which is the parent of the hook. The various hooks are:
beforeEach which runs before each individual it inside the describe call.
afterEach which runs after each individual it inside the describe call.
before which runs once before any of the individual it inside the describe call is run.
after which runs once after all the individual it inside the describe call are run.
These hooks can be used to acquire resources or create data structures needed for the tests and then release resources or destroy these structures (if needed) after the tests are done.
The snippet you show at the end of your question won't generate an error but it does not actually contain any test, because tests are defined by it.
It's hard to add to Louis' excellent answer. There are a couple of advantages of the describe block that he didn't mention which are the skip and only functions.
describe.skip(...) {
...
}
will skip this describe and all its nested describe and it functions while:
describe.only(...) {
...
}
will only execute that describe and its nested describe and it functions. The skip() and only() modifiers can also be applied to the it() functions.
To my knowledge, describe is really just there for humans... So we can see different areas of the app. You can nest describe n levels deep.
describe('user',function(){
describe('create',function(){}
});
Describe is just used for the sake of understanding the purpose of the tests , it is also used to logically group the tests . Lets say you are testing the database API's , all the database tests could come under the outer describe , so the outer describe logically groups all the database related . Lets say there are 10 database related API's to test , each of the inner describe functions defines what those tests are ....
The particular role of describe is to indicate which component is being tested and which method of that component is also being tested.
for example, lets say we have a User Prototype
var User = function() {
const self = this;
function setName(name) {
self.name = name
}
function getName(name) {
return self.name;
}
return{setName, getName};
}
module.exports = User;
And it needs to be tested, so a spec file is created for unit test
var assert = require('assert');
var User = require("../controllers/user.controller");
describe("User", function() {
describe('setName', function() {
it("should set the name on user", function() {
const pedro = new User();
name = "Pedro"
pedro.setName(name);
assert(pedro.getName(), name);
});
});
});
It is easy to see that the purpose of describe is indicating the component to be tested and the nested describe methods indicate which methods needs to be tested