I have several tests that do the same thing in mocha. This for me, it's duplication, and is the worst thing to do when you want your system to be maintenable.
var exerciseIsPetitionActive = function (expected, dateNow) { var actual = sut.isPetitionActive(dateNow); chai.assert.equal(expected, actual); }; test('test_isPetitionActive_calledWithDateUnderNumSeconds_returnTrue', function () { exerciseIsPetitionActive(true, new Date('2013-05-21 13:11:34')); }); test('test_isPetitionActive_calledWithDateGreaterThanNumSeconds_returnFalse', function () { exerciseIsPetitionActive(false, new Date('2013-05-21 13:12:35')); });
I need a way of collapsing my duplicated mocha tests in only one.
For example, in PhpUnit (and other test frameworks) you have dataProviders.
In phpUnit a dataProvider works this way:
<?php class DataTest extends PHPUnit_Framework_TestCase { /** * @dataProvider provider */ public function testAdd($a, $b, $c) { $this->assertEquals($c, $a + $b); } public function provider() { return array( array(0, 0, 0), array(0, 1, 1), array(1, 0, 1), array(1, 1, 3) ); } }
The provider in here injects parameters to the test, and the test executes all the cases. Is perfect for duplicated test.
I want to know if in mocha is there something similar, for example, something like this:
var exerciseIsPetitionActive = function (expected, dateNow) { var actual = sut.isPetitionActive(dateNow); chai.assert.equal(expected, actual); }; @usesDataProvider myDataProvider test('test_isPetitionActive_calledWithParams_returnCorrectAnswer', function (expected, date) { exerciseIsPetitionActive(expected, date); }); var myDataProvider = function() { return { {true, new Date(..)}, {false, new Date(...)} }; };
There is some tecnique that is called Shared Behaviours . But it does not solve the problem directly with a test suite, it just solve the problem with different components that have duplicated tests.
Do you know any way to implement dataProviders in mocha?
Mocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.
Mocha does not run individual tests in parallel. That means if you hand Mocha a single, lonely test file, it will spawn a single worker process, and that worker process will run the file. If you only have one test file, you'll be penalized for using parallel mode. Don't do that.
Learn how to run only one test with Mocha To run a single test (as defined in it() ), you can simply call the only() method on it in the following way: it. only('...', function () { // only this test will run... });
The beforeEach method is a feature (hook) in test libraries that you can use to set preconditions for each test. Just like the name suggests, it runs before each test in your test suite. For example, the beforeEach method will run four times in a suite with four tests.
A basic approach to run the same test with different data is to repeat the test in a loop providing the data:
describe('my tests', function () { var runs = [ {it: 'options1', options: {...}}, {it: 'options2', options: {...}}, ]; before(function () { ... }); runs.forEach(function (run) { it('does sth with ' + run.it, function () { ... }); }); });
before
runs, well, before all it
s in a describe
. If you need to use some of the options in before
, do not include it in the forEach
loop because mocha will first run all before
s and the all it
s, which is probably not wanted. You can either put the whole describe
in the loop:
var runs = [ {it: 'options1', options: {...}}, {it: 'options2', options: {...}}, ]; runs.forEach(function (run) { describe('my tests with ' + run.it, function () { before(function () { ... }); it('does sth with ' + run.it, function () { ... }); }); });
If you do not wish to pollute your tests with multiple describe
s, you can use the controversial module sinon
for this matter:
var sinon = require('sinon'); describe('my tests', function () { var runs = [ {it: 'options1', options: {...}}, {it: 'options2', options: {...}}, ]; // use a stub to return the proper configuration in `beforeEach` // otherwise `before` is called all times before all `it` calls var stub = sinon.stub(); runs.forEach(function (run, idx) { stub.onCall(idx).returns(run); }); beforeEach(function () { var run = stub(); // do something with the particular `run.options` }); runs.forEach(function (run, idx) { it('does sth with ' + run.it, function () { sinon.assert.callCount(stub, idx + 1); ... }); }); });
Sinon feels dirty but is effective. Several aid modules such as leche are based on sinon, but arguably introducing further complexity is not necessary.
Mocha doesn't provide a tool for that, but it is easy to do it yourself. You only need to run the tests inside a loop and give the data to the test function using a closure:
suite("my test suite", function () { var data = ["foo", "bar", "buzz"]; var testWithData = function (dataItem) { return function () { console.log(dataItem); //Here do your test. }; }; data.forEach(function (dataItem) { test("data_provider test", testWithData(dataItem)); }); });
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