I'm trying to join all the tests from multiple files in one file, something like this:
describe('Controllers', function() {
describe('messages.js', function() {
require('./controllertests/messages').test(options);
})
describe('users.js', function() {
require('./controllertests/users').test(options);
})
})
I'm pretty sure this is not the best way to join tests, I'm having some dificulty finding examples of how to do this :s
Mocha does not run individual tests in parallel. If you only have one test file, you'll be penalized for using parallel mode.
Introduction to Unit Testing with Mocha and Chai Mocha is a widely used JavaScript test framework running on NodeJS and browsers. It supports asynchronous testing running the tests serially, allowing for more flexible and accurate reporting.
If you want to include multiple modules into your describe
hierarchy like you are doing in your question, what you are doing is pretty much it, unless you want to write a custom test loader for Mocha. Writing the custom loader would not be easier or make your code clearer than what you already have.
Here's an example of how I would change a few things. The test
subdirectory in this example is organized as:
.
└── test
├── a
│ └── a.js
├── b
│ └── b.js
├── common.js
└── top.js
top.js
:
function importTest(name, path) {
describe(name, function () {
require(path);
});
}
var common = require("./common");
describe("top", function () {
beforeEach(function () {
console.log("running something before each test");
});
importTest("a", './a/a');
importTest("b", './b/b');
after(function () {
console.log("after all tests");
});
});
The importTest
function is just to show how it would be possible to handle the repetition of importing multiple modules without having to retype the whole describe(... require...
thing every single time. The common
module is meant to hold what you need to use in multiple modules of the test suite. I'm not actually using it in top
but it could be used there, if needed.
I will note here that the beforeEach
will run its code before each and every single test registered with it
whether they appear inside the describe
in top
or they appear in any of the modules imported. With --recursive
, the beforeEach
code would have to be copied into each module or perhaps you'd have a beforeEach
hook in each module that calls a function imported from a common module.
Also, the after
hook will run after all tests in the suite. This cannot be replicated with --recursive
. If you use --recursive
and add the code of after
to each module, it will be executed once per module rather than just once for the whole test.
Having all tests appear under a single top
heading cannot be replicated by using --recursive
. With --recursive
each file could have describe("top"
but this would create a new top
heading for each file.
common.js
:
var chai = require("chai");
var options = {
foo: "foo"
};
exports.options = options;
exports.chai = chai;
exports.assert = chai.assert;
Using a module named common
like this is something I've done in some of my test suites to avoid having to require
a bunch of stuff over and over and to hold global read-only variables or functions that don't keep state. I prefer not to pollute the global
object like in thgaskell's answer because this object is truly global and accessible even in third party libraries your code may be loading. This is not something I find acceptable in my code.
a/a.js
:
var common = require("../common");
var options = common.options;
var assert = common.assert;
it("blah a", function () {
console.log(options.foo);
assert.isTrue(false);
});
b/b.js
:
it("blah b", function () {});
Although this may not be directly linked to the question, the answer I was looking for was:
$ mocha --recursive
Will execute all tests in sub directories of the "test" folder. Neat. Saves having to maintain a list of tests that I want to load and actually just always run everything.
There's nothing that prevents you from running multiple test files. Generally, each test should not be dependent on the results of another test, so sharing variables isn't something you'd want to do.
Here's an example of how you could organize your test files.
.
├── app.js
└── test
├── common.js
├── mocha.opts
│
├── controllers
│ ├── messages-controller.js
│ └── users-controller.js
│
└── models
├── messages-model.js
└── users-model.js
Then inside of your mocha.opts
file, make sure to set the --recursive
option.
mocha.opts
--ui bdd
--recursive
If there are common modules that you want to include across all files, you can add that to the common.js
file. Files at the root of the test
directory will run before files in nested directories.
common.js
global.chai = require('chai');
global.assert = chai.assert;
global.expect = chai.expect;
chai.should();
chai.config.includeStack = true;
process.env.NODE_ENV = 'test';
// Include common modules from your application that will be used among multiple test suites.
global.myModule = require('../app/myModule');
I know this is an old post but I wanted to chime in with what has been a good solution to me, very similar to the method proposed by OP.
The project I'm working on is well tested and the tests keep growing. I ended up using require
because it is synchronous and therefore makes it a bit easier to compose your tests without too much change in architecture:
// inside test/index.js
describe('V1 ROUTES', () => {
require('./controllers/claims.test');
require('./controllers/claimDocuments.test');
require('./controllers/claimPhotos.test');
require('./controllers/inspections.test');
require('./controllers/inspectionPhotos.test');
require('./controllers/versions.test');
require('./services/login.v1.test');
});
describe('V2 ROUTES', () => {
require('./services/login.v2.test');
require('./services/dec-image.v2.test');
});
describe('V3 ROUTES', () => {
require('./services/login.v3.test');
require('./services/getInspectionPhotosv3.test');
require('./services/getPolicyInfo.v3.test');
});
describe('ACTIONS', () => {
require('./actions/notifications.test');
});
I had a similar problem where I had bunch of tests for classes in the same category and I wanted to group them together to make viewing them in an IDE easier. All of my tests and code were already using ES6 modules - I didn't want to rewrite all of them to use require
like I saw in other examples.
I solved it by having my "grouping" describe
exported, and then importing it into my test files and programmatically adding them to the imported describe
. I ended up creating a helper method to abstract away all of the plumbing.
In someCategory.spec.js
const someCategory= describe("someCategory", () => {});
// Use this just like a regular `describe` to create a child of this scope in another file
export default function describeMember(skillName, testFn) {
describe(skillName, function configureContext() {
// Make context a child of `someCategory` context
function Context() {}
Context.prototype = someCategory.ctx;
this.ctx = new Context();
// Re-parent the suite created by `describe` above (defaults to root scope of file it was created in)
this.parent.suites.pop();
someCategory.addSuite(this);
// Invoke the fn now that we've properly set up the parent/context
testFn.call(this);
});
}
In individual tests:
import { default as describeCategoryMember } from './someCategory.spec';
describeCategoryMember('something', () => {
describe('somethingElse', () => {
...
});
it('a test', () => {
...
});
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With