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
describedoes not support promises which was the purpose of this issue.I just wanted to tack on to what @WORMSS said in 2018 because while
importwas a “nice to have” it’s now required in the official standard of Node.js sincerequiredoesn’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
describeblocks 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
--delayoption, although that still requires the entiredescribeto occur after the asynchronous info is obtained (itstill must be called synchronously insidedescribebefore thedescribereturns).If you don’t need the data to define the tests but only to run them, you can use async
before/beforeEachhooks 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/beforeEachsince 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
describewould wait for promises the same wayitdoes. I can work around it, but it would be wonderful ifdescribecould just recognizeasyncfunctions 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
describewere 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
requiretoimportto 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 Passedwhen 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
importI 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
describeviolates the golden rule of predictable behavior. If asyncitis supported, it’s reasonable to assume that asyncdescribeshould also works.For me, the main reason for using async
describeis 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…