Reputation: 638
Hei guys,
I'd like to execute this test-cases sequentially with mocha. This means using the result of a previous test for the next one. But how to do that?
describe('some test', function(){
var x;
it('do something', function(done){
x = [10, 20, 30];
done();
});
// dynamic test
x.forEach(function(i){
it('test number '+i, function(done){
setTimeout(function(){
done();
}, 500);
});
});
it('do something else', function(done){
done();
});
});
The current issue is that the forEach is always executed before x being assigned and this raise a Cannot ready property 'forEach' of undefined error.
This is the output I'd like to have:
some test:
- do something
- test number 1
- test number 2
- test number 3
- do something else
Upvotes: 0
Views: 2049
Reputation: 638
This might be the right way to handle this. Using run with the delay option (mocha.delay() in the browser, --delay on the commandline), which allows mocha to wait to run till you call run() to tell it you're done adding tests:
describe('using asynchronously acquired data', function(){
var x; // This is only needed if also using non-dynamically-generated tests on the same data.
getDataFromSomewhereAsynchronously(function(data){
x = data; // This is only needed if also using non-dynamically-generated tests on the same data.
data.forEach(function(dataItem, index){
it('dynamically generated test number ' + (index + 1), function(){
assert.whateverYouDoWithThisData(dataItem);
});
});
run();
});
it('non-dynamically-generated test using asynchronously acquired data', function() {
assert.whateverYouNeedToCheck(x);
});
});
Thanks @ScottFreeCode for the answer.
If your "x" data is retrieved from a test itself, the above solution wouldn't work. So a better workaround would be doing all the job inside one unique it-statement (so use a loop inside the it-statement). But in that way we'll have to deal with timeout issues probably (especially for chained REST calls). So better put a this.timeout() increasing linearly.
this.timeout(x.length * 1000); // 1 second per single-data
Upvotes: 0
Reputation: 1518
This is not the answer you want, but I believe it's worth mentioning.
You should always strive for independent tests. Having tests depend on each other leaves you with unnecessary issues.
Just to mention a few; you'll have to deal with running tests in the right order and you'll find that when one test fails, the test dependent on the first will fail as well.
Look at this excellent answer about what makes a good unit test
Upvotes: 0
Reputation: 203231
The body of a describe()
block is always executed immediately. This allows dynamic tests to be created (like you're trying to do), but also registers all test parts with Mocha.
However, because of this, any parts of the actual testing, like before()
blocks, can't be used to configure the dynamic test setup.
Instead, you can just use this (I've also taken the liberty of rewriting the for
loop into something a bit more readable, IMO):
describe('some test', function() {
var x = [ 10, 20, 30 ];
// dynamic test
x.forEach(function(value, i) {
it('test number ' + i, function(done){
setTimeout(function(){
done();
}, 500);
});
});
it('do something else', function(done){
done();
});
});
However, if it's your intention that x
is somehow retrieved dynamically during testing, this won't work either, and I'm not actually sure if it's possible to create dynamic tests based on a value that itself is dynamicly generated as part of a test.
Upvotes: 1