如何让Mocha测试等待非Promise代码执行完成?
我完全懂你遇到的困扰——明明用了done(),但Mocha还是没等测试里的操作完成就生成了报告。问题出在你没正确处理enterValue方法内部的异步逻辑,虽然调用看起来是同步的,但它底层是Promise操作,你现在的写法相当于直接跳过等待,告诉Mocha“我做完了”,但实际上那些异步操作还在跑呢。
问题本质
homepg.name().enterValue('user1')和homepg.group().enterValue('grp1')这两个调用,表面是同步执行,但它们内部封装了Promise异步逻辑。你现在写完这两行就立刻调用done(),Mocha会直接结束这个测试块,完全不会等内部的Promise完成,自然就出现了报告提前生成的情况。
解决方案
根据你的场景,有两种最靠谱的处理方式:
1. 用async/await(推荐,代码更清晰)
如果你的enterValue方法本身会返回Promise,直接用async函数配合await就能让Mocha自动等待所有异步操作完成:
it('Fill in the details', async function() { // 等待第一个输入操作完成 await homepg.name().enterValue('user1'); // 再等待第二个输入操作完成 await homepg.group().enterValue('grp1'); });
Mocha会自动识别async函数,直到所有await的Promise都resolve,才会结束这个测试块。
2. 用Promise链式调用配合done()
如果你更习惯用done回调,那必须把done()放在Promise的回调里,确保所有异步操作完成后再通知Mocha:
it('Fill in the details', function(done) { homepg.name().enterValue('user1') .then(() => { // 第一个操作完成后,执行第二个 return homepg.group().enterValue('grp1'); }) .then(() => { // 所有操作都完成了,告诉Mocha测试结束 done(); }) .catch(err => { // 别忘了处理错误,否则Mocha会因为超时失败 done(err); }); });
关键提醒
如果你的enterValue方法没有返回内部的Promise,那第一步得修改这个方法,让它把内部的Promise暴露出来。因为Mocha只能通过Promise或者done()来感知异步操作,要是方法内部异步但不对外返回Promise,外部根本没法等待它完成。
这样调整后,Mocha就会老老实实等所有测试操作完成,再生成正确的测试报告啦。
内容的提问来源于stack exchange,提问作者riya

