describe('some tests', function () {
/*
* Run some tests...
*/
})
after(function () {
failures = ? // <--- what goes here?
console.log(failures + " tests failed!")
})
I'd use this to keep chromedriver's browser open if a test failed, and to report success or failure to sauce labs.
Mocha's Runner and Reporters have the info I'm looking for as stats
but I'm not sure how to get to them from within a test file.
I found answer to this question here
afterEach(function() {
if (this.currentTest.state == 'failed') {
// ...
}
});
After a quick check of the code, I believe there is no way for code in after
to have access to the runner or the reporters. However, there's a way to get the state of the tests at run time:
describe("blah", function () {
it("blah", function () {
throw new Error("blah");
});
after(function (){
var failed = false;
var tests = this.test.parent.tests;
for(var i = 0, limit = tests.length; !failed && i < limit; ++i)
failed = tests[i].state === "failed";
if (failed)
console.log("FAILED");
});
});
Look at the line var tests = this.test.parent.tests
. I believe that this.test
seems to be a test object associated with the after
call. The value of this.test.parent
is the suite object associated with the top level describe
. And the value of this.test.parent.tests
is the list of tests in that suite. So the code there goes through each test, and detects whether the test is in the "failed"
state.
None of the variables used in the code above are marked as private (by use of a leading underscore in the name). At the same time, there are no guarantees that future versions of Mocha will use the exact same structure.
All test failures are exceptions so to catch hook failures, I'd wrap the hook with code that detects exceptions. This is a proof-of-concept that shows how it could be done (and I've moved some of the code in the previous example into a has_failed
function):
var hook_failure = false;
function make_wrapper(f) {
return function wrapper() {
try {
f.apply(this, arguments);
}
catch (e) {
hook_failure = true;
throw e;
}
};
}
function has_failed(it) {
var failed = false;
var tests = it.test.parent.tests;
for(var i = 0, limit = tests.length; !failed && i < limit; ++i)
failed = tests[i].state === "failed";
return failed;
}
describe("blah", function () {
before(make_wrapper(function () {
throw new Error("yikes!");
}));
it("blah", function () {
throw new Error("q");
});
after(function (){
var failed = has_failed(this);
if (failed)
console.log(this.test.parent.title + " FAILED");
});
});
after(function () {
if (hook_failure)
console.log("HOOK FAILURE");
});
In the example above I use the wrapper method and the method of scanning tests in after
. However, it would be possible to only use wrappers throughout for hooks and tests.
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