如何异步构建测试套件? [英] How can I build my test suite asynchronously?
问题描述
我正在尝试使用必须异步加载的配置为我的控制器创建摩卡测试.下面是我的代码.但是,运行mocha测试时,它不会运行任何测试,并显示0 passing
. console.log
甚至都不会被调用.我尝试在describe内执行before(next => config.build().then(next))
,但是即使运行测试,也不会调用before
.有没有一种方法可以在运行任何测试之前一次加载配置?
I'm trying to create mocha tests for my controllers using a config that has to be loaded async. Below is my code. However, when the mocha test is run, it doesn't run any tests, displaying 0 passing
. The console.log
s are never even called. I tried doing before(next => config.build().then(next))
inside of the describe, but even though the tests run, before
is never called. Is there a way to have the config be loaded one time before any tests are run?
'use strict';
const common = require('./common');
const config = require('../config');
config
.build()
.then(test);
function test() {
console.log(1);
describe('Unit Testing', () => {
console.log(2);
require('./auth');
});
}
推荐答案
您应该使用--delay
选项运行Mocha,然后在完成测试套件的构建后使用run()
.这是从您在问题中显示的代码派生的示例:
You should run Mocha with the --delay
option, and then use run()
once you are done building your test suite. Here is an example derived from the code you show in the question:
'use strict';
function test() {
console.log(1);
describe('Unit Testing', () => {
console.log(2);
it("test", () => {
console.log(3);
});
});
// You must use --delay for `run()` to be available to you.
run();
}
setTimeout(test, 1000);
我正在使用setTimeout
模拟异步操作.使用--delay
和run()
允许您构建作为异步计算结果的套件.但是请注意,该套件必须一次性构建. (在describe
中不能有一个异步进程来调用it
.这将不起作用.)
I'm using setTimeout
to simulate an asynchronous operation. Using --delay
and run()
allows you to build a suite that is the result of an asynchronous computation. Note, however, that the suite must be built in one shot. (You cannot have an asynchronous process inside describe
that will make calls to it
. This won't work.)
您绝对不应该做的一件事就是rob3c 建议:调用describe
或it
(或同时调用两者) )从一个钩子里面.这是每个人不时犯的错误,因此值得详细解决.问题是Mocha不支持它,因此没有与从挂钩内部调用describe
或it
相关的已建立语义.哦,有可能写一些简单的示例,但可以像预期的那样工作:
One thing you should definitely not do is what rob3c suggests: calling describe
or it
(or both) from inside a hook. This is a mistake that every now and then people make so it is worth addressing in details. The problem is that it is just not supported by Mocha, and therefore there are no established semantics associated with calling describe
or it
from inside a hook. Oh, it is possible to write simple examples that work as one might expect but:
-
当套件变得更加复杂时,套件的行为不再对应于任何明智的行为.
When the suite becomes more complex, the suite's behavior no longer corresponds to anything sensible.
由于这种方法没有语义,因此较新的Mocha版本可能会以不同方式处理错误用法并破坏套件.
Since there are no semantics associated with this approach, newer Mocha releases may handle the erroneous usage differently and break your suite.
考虑以下简单示例:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]);
describe("top", () => {
let flag;
before(() => {
flag = true;
return p.then((names) => {
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
});
});
after(() => {
flag = false;
});
it("regular test", () => {
assert(flag);
});
});
运行它,我们得到:
top
✓ regular test
embedded
1) foo
2) bar
3) baz
1 passing (32ms)
3 failing
// [stack traces omitted for brevity]
这是怎么回事?所有的测试不应该通过吗?我们在before
钩子中将flag
设置为true
,以描述top
.我们在其中创建的所有测试都应将flag
视为true
,不是吗?线索在上面的输出中:当我们在一个钩子中创建测试时,Mocha会将测试放在某处,但是它可能不在反映代码中describe
块结构的位置. 在这种情况下发生的情况是,因为Mocha只是将在钩子中创建的测试附加到套件的末尾,在top
描述之外,因此after
钩子在动态创建的测试之前运行,我们得到了违反直觉的结果.
What's going on here? Shouldn't all the tests pass? We set flag
to true
in the before
hook for the top
describe. All tests we create in it should see flag
as true
, no? The clue is in the output above: when we create tests inside a hook, Mocha will put the tests somewhere but it may not be in a location that reflects the structure of the describe
blocks in the code. What happens in this case is that Mocha just appends the tests created in the hook the the very end of the suite, outside the top
describe, so the after
hook runs before the dynamically created tests, and we get a counter-intuitive result.
使用--delay
和run()
,我们可以编写一套与直觉相符的套件:
Using --delay
and run()
, we can write a suite that behaves in a way concordant with intuition:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]).then((names) => {
describe("top", () => {
let flag;
before(() => {
flag = true;
});
after(() => {
flag = false;
});
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
it("regular test", () => {
assert(flag);
});
});
run();
});
输出:
top
✓ regular test
embedded
✓ foo
✓ bar
✓ baz
4 passing (19ms)
这篇关于如何异步构建测试套件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!