mocha: Describe block with async function behaving weirdly
Mocha 3.5 Node 8.4
describe('Test Suite 1', async function(){
let email = await faker.internet.email();
it('should print email', function(){
email.should.not.be.a('string')
)}
})
Running this test should give
Test Suite 1
✓should print email
But its giving
0 passing
Also modifying the above code to
describe('Test Suite 1', async function(){
let email;
it('should print email', async function(){
email = await faker.internet.email()
email.should.not.be.a('string')
)}
})
Runs the test but doesn’t print the name of describe i.e Test Suite 1
✓should print email
Removing the async from describe and putting it in it works fine
describe('Test Suite 1', function(){
it('should print email',async function(){
let email = await faker.internet.email();
email.should.not.be.a('string')
)}
})
Test Suite 1
✓should print email
Also .only and .skip do not work when async function is included in the describe block
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 28
- Comments: 40 (10 by maintainers)
Commits related to this issue
- Fix doc walker tests not running See https://github.com/mochajs/mocha/issues/2975. — committed to Levertion/mcfunction-langserver by Levertion 6 years ago
- docs: Add warning about async callback for describe I couldn't find any reference to `describe` not supporting an async function. It seems like a natural idea given `it` and `before` do. I spent c... — committed to mcdurdin/mocha by mcdurdin 7 months ago
- fix(web): mocha describe does not do async mocha describe() does not accept an async function. Any async prep should be done in a before() function, which does support async. One helpful ref: https:... — committed to keymanapp/keyman by mcdurdin 7 months ago
@ondratra, why can’t
before()
work for you?“test.ts”
Is there any plan to fix this in the long term?
I am aware that that switching to imports results in the tests not executing. I assume this is because the import function returns a promise and
describe
does not support promises which was the purpose of this issue.I just wanted to tack on to what @WORMSS said in 2018 because while
import
was a “nice to have” it’s now required in the official standard of Node.js sincerequire
doesn’t exist in ESM.I can only hope Mocha devs will support this syntax in the future.
this would help a lot with maintaining large code bases. (TBF I’ve only got like 100 test files, I would be desperate for this if I had 4200 lol)
Async functions are syntactic sugar for returned promise chains, and Mocha’s
describe
blocks do not support (as in waiting for resolution of) returned promises. Failing to warn about it is perhaps less helpful than it could be, but the behavior is pretty much expected under the current design.For cases where the names of the tests or how many tests there are can only be determined asynchronously, there is the
--delay
option, although that still requires the entiredescribe
to occur after the asynchronous info is obtained (it
still must be called synchronously insidedescribe
before thedescribe
returns).If you don’t need the data to define the tests but only to run them, you can use async
before
/beforeEach
hooks to get it (that would be the obvious way to do these trivial examples), or even async tests with the initial methods to obtain the data written into the start of the test.If you can come up with a real use case where
--delay
’s limitations are needlessly awkward but it can’t just be done withbefore
/beforeEach
since the definition of tests depends on it, then a case could be made for adding promise support (from which async function support would automatically be derived) todescribe
.I struggled with this same problem for a while (certain tests mysteriously not running) until I found this issue posted. I had just assumed
describe
would wait for promises the same wayit
does. I can work around it, but it would be wonderful ifdescribe
could just recognizeasync
functions and behave accordingly.@boneskull can we reopen this as it’s still not fixed?
In TypeScript projects, the lack of ability to use async describe functions leads to the following:
I want to write:
What I need to write:
It would be quite handy if
describe
were to wait for the promise to resolve if one was returned. Is that possibility, or is there something fundamental that prevents this from ever happening.I’d use this approach
I want to fetch test data and use it to partially apply a validation function. doing it in beforeEach would defeat the purpose, since I wouldn’t have the data outside the scope of the test
wanted to add to this by mentioning that ESM is now the official standard for Node.js and require is no longer available within ESM scope.
I do love splitting up my tests this way and I hope Mocha can support asynchronously importing test files in the future. IMHO this issue should be opened back up.
[edit]: it also looks like people were looking at Jest to support the same thing for similar reasons => https://github.com/facebook/jest/issues/2235
Just to add to the discussion that our company got caught out by the non-async nature of describe when a developer changed from
require
toimport
to match the rest of the system. Sadly this caused no errors, and was only during the addition of.only()
by myself that the test reported0 Passed
when I knew there should be 38 that either passed or failed.`We went back to the original and now works as expected, but I think we would prefer to use
import
I believe they want to keep the “build up the structure of where the tests are” as synchronous as possible.
@juergba it looks like more and more people are falling into this trap. It’s a bit dangerous when the testing tool just stops running part of the tests without any errors or warnings. And the lack of support for asynchronous
describe
violates the golden rule of predictable behavior. If asyncit
is supported, it’s reasonable to assume that asyncdescribe
should also works.For me, the main reason for using async
describe
is to import ESM modules. And even if there are several stages of test execution, why not wait for asyncdescribe
?That --fail-zero would only help if ALL your tests were in that one describe… Only about 400 test were in the aqs.utils location. The other 4200 tests were scattered throughout many other files. As I said back in 2018, it was ONLY because I used
.only(
that I even noticed this problem at all.I have found another way to get things done. May be this could work for someone.
That’s how I achieved the assertion on every element of the array. (Array data is being fetch asynchronously). Kindly correct me if I’m doing it wrong.
LOL…
“.flowconfig”
Maybe…