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 #
.)
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)
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
.
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
.