In the previous chapter, we installed and introduced Mocha. Mocha is a JavaScript test framework that runs inside Node.js or inside a browser. You can use it to define and run your own tests. Mocha reports back on the outcome: which tests ran fine and which tests failed and where any failures occurred. Mocha runs each of the tests in turn, waiting for one test to finish or timeout before running the next one.
Even though Mocha is designed to be able to run on any modern browser, we will only be running it through Node.js via the command line. There are other things Mocha can do, which will be explained in this chapter. For a more complete reference to Mocha's capabilities, please visit Mocha's official documentation website, http://visionmedia.github.com/mocha/ to find out more.
The topics covered in this chapter include:
By the end of this chapter, you should be able to use Mocha to perform asynchronous tests and understand how Mocha controls test flow.
There are two strategies you can use to organize your tests. The first is to divide them somehow into separate files, each file representing a functional or logical unit of your application. The other strategy, which can be used in tandem with the first one, is to group them by feature.
Having a separate file for each functional unit of your app is a good way of separating your testing concerns. You should analyze the structure of your application and separate it into distinct concerns that have a minimum amount of overlap. For instance, your application may have to deal with user registrations—that could be one functional group. Another functional group may be user login. If your application deals with to-do lists, you may want to have a separate file that contains the tests for that part of your application.
By having separate files for each functional group, you can call your tests in isolation while you're working on that particular group. This technique also allows you to keep the line count low on each file, which is helpful when you're navigating and maintaining your tests.
Describing features: When defining your tests, you can also group application functionality by feature. For instance, when describing the to-do list functionality, you could further separate these features as follows:
Within our test scripts, we would describe the previously mentioned testable to-do features.
The layout of the to-do items test file could then be as follows:
describe('To-do items', function() { describe('creating', function() { // to-do item creating tests here... }); describe('removing', function() { // removing a to-do item tests here... }); describe('showing', function() { // to-do item list showing tests here... }); describe('ordering', function() { // to-do item ordering tests here... }); });
You can nest as many describe
statements as you wish, refining the scope of the tests as much as you want, but as a rule of thumb, you should use two description levels: one for the functional group (for instance, to-do items) and another level for each feature. Inside each feature definition, you can place all the relevant tests.