我假设您对笑话和单元测试有基本的了解。我不会解释钩子的含义。这更多的是备忘单/参考类型的帖子。
乍一看,笑话似乎有神奇的作用。什么时候执行什么?但如果你想一想,它就会变得明显不那么令人困惑。
也许这些简单的“规则”有帮助:
console.log("./<start>"); beforeall(() => { console.log("./beforeall"); }) beforeeach(() => { console.log("./beforeeach"); }) afterall(() => { console.log("./afterall"); }) aftereach(() => { console.log("./aftereach"); }) describe("foo", () => { console.log("./describe(foo)/<start>"); beforeall(() => { console.log("./describe(foo)/beforeall"); }) beforeeach(() => { console.log("./describe(foo)/beforeeach"); }) afterall(() => { console.log("./describe(foo)/afterall"); }) aftereach(() => { console.log("./describe(foo)/aftereach"); }) test("testfoo", () => { console.log("./describe(foo)/test(testfoo)"); }) console.log("./describe(foo)/<end>"); }) describe("bar", () => { console.log("./describe(bar)/<start>"); beforeall(() => { console.log("./describe(bar)/beforeall"); }) beforeeach(() => { console.log("./describe(bar)/beforeeach"); }) afterall(() => { console.log("./describe(bar)/afterall"); }) aftereach(() => { console.log("./describe(bar)/aftereach"); }) test("testbar", () => { console.log("./describe(bar)/test(testbar)"); }) test("testotherbar", () => { console.log("./describe(bar)/test(testotherbar)"); }) console.log("./describe(bar)/<end>"); }) console.log("./<end>"); </end></end></start></end></start></start>
这是结果(在我删除其他输出后):
./<start> ./describe(foo)/<start> ./describe(foo)/<end> ./describe(bar)/<start> ./describe(bar)/<end> ./<end> ./beforeall ./describe(foo)/beforeall ./beforeeach ./describe(foo)/beforeeach ./describe(foo)/test(testfoo) ./describe(foo)/aftereach ./aftereach ./describe(foo)/afterall ./describe(bar)/beforeall ./beforeeach ./describe(bar)/beforeeach ./describe(bar)/test(testbar) ./describe(bar)/aftereach ./aftereach ./beforeeach ./describe(bar)/beforeeach ./describe(bar)/test(testotherbar) ./describe(bar)/aftereach ./aftereach ./describe(bar)/afterall ./afterall </end></end></start></end></start></start>
顶层和描述回调中的所有内容都会立即执行:
./<start> ./describe(foo)/<start> ./describe(foo)/<end> ./describe(bar)/<start> ./describe(bar)/<end> ./<end> [...] </end></end></start></end></start></start>
顶层的 beforeall 和 afterall 是所有测试的“支撑”。每个只执行一次。
[...] ./beforeall [...] ./afterall
./describe(*)/beforeall 和 ./describe(*)/afterall 是 that 描述回调中所有测试的大括号。每个只执行一次。
[...] ./describe(foo)/beforeall [...] ./describe(foo)/afterall ./describe(bar)/beforeall [...] ./describe(bar)/afterall [...]
beforeeach 和 aftereach 是每个测试周围的大括号。最顶层是外大括号。描述级别是内部大括号。
[...] ./beforeeach ./describe(*)/beforeeach [...] ./describe(*)/aftereach ./aftereach [...]
这是一个带有嵌套描述块的高级示例。它生成 xmlish 结果来强调执行步骤的分层性质。
console.log("<top-level>"); beforeall(() => { console.log("<all>"); }) beforeeach(() => { console.log("<each>"); }) afterall(() => { console.log("</each></all>"); }) aftereach(() => { console.log(""); }) describe("foo", () => { console.log("<describe id='\"foo\"'>"); beforeall(() => { console.log("<all in='\"foo\"'>"); }) beforeeach(() => { console.log("<each in='\"foo\"'>"); }) afterall(() => { console.log("</each></all><!-- in=\"foo\" -->"); }) aftereach(() => { console.log(" <!-- in=\"foo\" -->"); }) test("testfoo", () => { console.log("<test in='\"foo\"' id='\"testfoo\"'></test>"); }) console.log("</describe><!-- id=\"foo\" -->"); }) describe("bar", () => { describe("barinner", () => { console.log("<describe id='\"barinner\"'>"); beforeall(() => { console.log("<all in='\"barinner\"'>"); }) beforeeach(() => { console.log("<each in='\"barinner\"'>"); }) afterall(() => { console.log("</each></all><!-- in=\"barinner\" -->"); }) aftereach(() => { console.log(" <!-- in=\"barinner\" -->"); }) test("testbarinner", () => { console.log("<test in='\"barinner\"' id='\"testbarinner\"'></test>"); }) console.log("</describe><!-- id=\"barinner\" -->"); }) console.log("<describe id='\"bar\"'>"); beforeall(() => { console.log("<all in='\"bar\"'>"); }) beforeeach(() => { console.log("<each in='\"bar\"'>"); }) afterall(() => { console.log("</each></all><!-- in=\"bar\" -->"); }) aftereach(() => { console.log(" <!-- in=\"bar\" -->"); }) test("testbar", () => { console.log("<test in='\"bar\"' id='\"testbar\"'></test>"); }) test("testotherbar", () => { console.log("<test in='\"bar\"' id='\"testotherbar\"'></test>"); }) console.log("</describe><!-- id=\"bar\" -->"); }) console.log("</top-level>");
这是经过一些清理和格式化后的输出:
<top-level><describe id="foo"></describe><!-- id="foo" --><describe id="barinner"></describe><!-- id="barinner" --><describe id="bar"></describe><!-- id="bar" --></top-level><all><all in="foo"><each><each in="foo"><test in="foo" id="testFoo"></test></each><!-- in="foo" --></each></all><!-- in="foo" --><all in="bar"><all in="barinner"><each><each in="bar"><each in="barinner"><test in="barinner" id="testBarInner"></test></each><!-- in="barinner" --></each><!-- in="bar" --></each></all><!-- in="barinner" --><each><each in="bar"><test in="bar" id="testBar"></test></each><!-- in="bar" --></each><each><each in="bar"><test in="bar" id="otherBar"></test></each><!-- in="bar" --></each></all><!-- in="bar" --></all>
这就是关于执行顺序的全部知识。