An Introduction to Mocha
What is Mocha?
Mocha is a feature-rich JavaScript test framework running on node and the browser, making asynchronous testing simple and fun.
If you're interested in writing tests for your JavaScript code, Mocha is a good way to start.
Advantages
- Runs on both Node.js and the browser.
- Allows for regular and async testing.
- Allows use of any assertion library you want.
- Tests can be written in a BDD, TDD or other styles.
- Has a variety of test results reporters.
- Built-in file watching support.
- and more.
Testing with Mocha
Installation
First, you need to have Node.js installed (and npm).
To install:
1 | npm install -g mocha |
This installs Mocha globally so that you can use the command everywhere.
How to use
1 2 3 4 5 6 7 8 9 10 11 12 | var assert = require('assert'); describe('String', function () { describe('#indexOf', function () { it('should return -1 when the substring is not present', function () { var myString = 'test'; assert.equal(-1, myString.indexOf('x')); assert.equal(-1, myString.indexOf('y')); }); }); }); |
Let's save the above code as a test.js
file. We'd run the test like this:
1 | mocha test.js |
By default, if you don't specify a file or folder, Mocha will run all tests in
the test
folder where you're running the command.
Let's leverage that and move the file to a test
folder. Run:
1 | mocha |
And the same output should show up.
Recursive
If you have a folder structure with lots of files and in your test
folder you
can run mocha with the --recursive
option:
1 | mocha --recursive |
This will find and run every test file on every folder.
Reporters
Now, our output, although colored, looks kind of weak:
1 2 3 4 | . ✓ 1 test complete (5 ms) |
Luckily, Mocha provides several reporters for us to choose how we'd like our test results output to look like.
My preference is to use the spec
reporter. We can use it like so:
1 2 3 | mocha -R spec
# or
mocha --reporter spec
|
To which the output now would be:
1 2 3 4 5 6 | String #indexOf ✓ should return -1 when the substring is not present 1 test complete (7 ms) |
mocha.opts
We can save an options file called mocha.opts
where we can specify
command-line options to pass to Mocha. Say, every time we run our our tests
we'd like it to be recursive, use the spec reporter and exit on the first
failed test:
1 2 3 | ---recursive ---reporter spec ---bail |
Assertions
Mocha doesn't have a built-in assertion system. In fact, if you hadn't noticed,
the test example is using Node.js' assert
module because, again, Mocha doesn't have
one.
This can be thought of as both good and bad, but let's try to keep an open mind.
With Mocha we can use any assertion library we want to make our tests.
Here are some options listed on the website:
The one I have experimented with is chai, specifically, chai's expect assertion.
How would we rewrite the example using chai's expect? Let's first install it:
1 | npm install chai |
We'd have to require chai's expect
.
1 | var expect = require('chai').expect; |
And instead of saying assert.equal
we would do something like expect
this
value to be equal to this other value:
1 2 3 4 5 6 7 8 9 10 11 12 | var expect = require('chai').expect; describe('String', function () { describe('#indexOf', function () { it('should return -1 when the substring is not present', function () { var myString = 'test'; expect(myString.indexOf('x')).to.equal(-1); expect(myString.indexOf('y')).to.equal(-1); }); }); }); |
The difference is subtle, but significant in readability. If you're not very fond of this style, chai has two other styles and if you don't like those, try another library.
Conclusion
I like it, ha. I like it because it has so many options, because it has useful things already baked in, because it's easy, flexible, pluggable and configurable.
Go take a look at the docs, I didn't write about a lot of awesome Mocha stuff.
Sources: