In association with heise online

Writing tests

Writing a test in Mocha is easy: for every test, call the pre-configured test function and submit the name of the required test to it.

test('Numbers divisible by 3 return Fizz');

However, this will only work if the --ui tdd command line parameter that enables the TDD (Test-Driven Development) style is added when calling Mocha. When using the default BDD (Behaviour-Driven Development) style, the name of the function to be called is it:

it('should return Fizz for numbers divisible by 3');

At least in Mocha, a developer's style preference is a purely syntactical matter and has no effect on the available features or any other aspects. As the author of this article favours the TDD style, all following examples will be listed in this style without any further explanation.

When executing Mocha, the test will be marked as inconclusive because, although it won't fail, it doesn't include an implementation. The implementation is submitted to the test function as a second parameter within a callback:

test('Numbers divisible by 3 return Fizz', function () {
// ...
});

The internal logic of Mocha works in a relatively simple way: if the callback is executed successfully without causing an exception, the test result is considered a pass – otherwise, the test is considered to have failed.

Mocha will always leave it up to developers to choose the actual module for handling the assert phase. Therefore, the integrated assert module of Node.js that was mentioned earlier may optionally be used. Alternatively, however, there are a multitude of other relevant third-party modules that cover almost any conceivable style. A small overview is available in the supplementary information under "Assert, should, etc".

Tests that require more than 75 milliseconds to complete are considered "slow" and will be marked accordingly in most output formats. If Mocha needs more than 2000 milliseconds to execute a test, it will abort it and consider it failed. This timeout can be determined globally via the --timeout parameter, but it can also be set individually for each test. To do so, call the timeout function from this within a test and append the number of milliseconds that you want the program to wait before it aborts a test:

test('Numbers divisible by 3 return Fizz', function () {
this.timeout(5 * 1000);
// ...
});

Structuring tests

Mocha offers simple but powerful tools for providing clear test structures. A test file of the same name will be created for every file that is to be tested, and an optional tests suffix can be added for enhanced readability. Mocha will clone the application's underlying directory structure within the test directory, creating the following structure:

/
+- foo.js
+- bar
! +- baz.js
+- test
+- fooTests.js
+- mocha.opts
+- bar
+- bazTests.js

The only aspect to consider in this scenario is that Mocha must be called with the --recursive parameter, or that this parameter must be added to the mocha.opts file, so that the framework will include the test directory's subdirectories when searching for test files.

Within a test file, Mocha will also create a separate test for each test case. However, their number can potentially grow to enormous proportions. To provide a better overview, it would be good to have the ability to further group individual tests in logical containers within a file. Mocha's suite function provides this functionality; it behaves in a similar manner to the test function, but it only defines a test container, not an actual test.

suite('isFizz', function () {
test('returns true for numbers divisible by 3', function () {
// ...
});
test('returns false for numbers not divisible by 3', function () {
// ...
});
});

Conveniently, test containers themselves can be nested in different ways:

suite('fizzBuzz', function () {
suite('isFizz', function () {
// ...
});
suite('isBuzz', function () {
// ...
});
});

If the BDD style is used instead of TDD, Mocha will use describe instead of suite as the name of the container function. Apart from this naming difference, both functions behave identically.

Next page: Inits, asserts and async tests

Print Version | Permalink: http://h-online.com/-1829727
  • Twitter
  • Facebook
  • submit to slashdot
  • StumbleUpon
  • submit to reddit
 


  • July's Community Calendar





The H Open

The H Security

The H Developer

The H Internet Toolkit