插件窝 干货文章 笑话回顾:什么时候运行?

笑话回顾:什么时候运行?

describe gt console lt 352    来源:    2024-10-23

tl;dr:执行顺序

  1. 顶层和describe() 块中的所有内容(其中describe() 块基本上是iife)
  2. 之前所有()
    1. 顶级
    2. 第一级描述()
    3. 第n级describe()
  3. 在每个()之前
    1. 顶级
    2. 第一级描述()
    3. 第n级describe()
  4. 测试()
  5. 每个之后()
    1. 第n级describe()
    2. 第一级描述()
    3. 顶级
  6. 毕竟()
    1. 第n级describe()
    2. 第一级描述()
    3. 顶级

免责声明

我假设您对笑话和单元测试有基本的了解。我不会解释钩子的含义。这更多的是备忘单/参考类型的帖子。

有规则

乍一看,笑话似乎有神奇的作用。什么时候执行什么?但如果你想一想,它就会变得明显不那么令人困惑。

也许这些简单的“规则”有帮助:

  1. 每个文件都是独立执行的:您在 a.test.js 中所做的任何操作都不会影响 b.test.js。 (除非你开始访问外部资源)
  2. describe() 回调会立即执行。
  3. 钩子(beforeall/afterall、beforeeach/aftereach)从外部作用域(顶级/模块)到内部作用域(描述)执行。

基本示例

console.log("./<start>");

beforeall(() =&gt; {
    console.log("./beforeall");
})
beforeeach(() =&gt; {
    console.log("./beforeeach");
})
afterall(() =&gt; {
    console.log("./afterall");
})
aftereach(() =&gt; {
    console.log("./aftereach");
})

describe("foo", () =&gt; {
    console.log("./describe(foo)/<start>");

    beforeall(() =&gt; {
        console.log("./describe(foo)/beforeall");
    })
    beforeeach(() =&gt; {
        console.log("./describe(foo)/beforeeach");
    })
    afterall(() =&gt; {
        console.log("./describe(foo)/afterall");
    })
    aftereach(() =&gt; {
        console.log("./describe(foo)/aftereach");
    })

    test("testfoo", () =&gt; {
        console.log("./describe(foo)/test(testfoo)");
    })

    console.log("./describe(foo)/<end>");
})

describe("bar", () =&gt; {
    console.log("./describe(bar)/<start>");

    beforeall(() =&gt; {
        console.log("./describe(bar)/beforeall");
    })
    beforeeach(() =&gt; {
        console.log("./describe(bar)/beforeeach");
    })
    afterall(() =&gt; {
        console.log("./describe(bar)/afterall");
    })
    aftereach(() =&gt; {
        console.log("./describe(bar)/aftereach");
    })

    test("testbar", () =&gt; {
        console.log("./describe(bar)/test(testbar)");
    })
    test("testotherbar", () =&gt; {
        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(() =&gt; {
    console.log("<all>");
})
beforeeach(() =&gt; {
    console.log("<each>");
})
afterall(() =&gt; {
    console.log("</each></all>");
})
aftereach(() =&gt; {
    console.log("");
})

describe("foo", () =&gt; {
    console.log("<describe id='\"foo\"'>");

    beforeall(() =&gt; {
        console.log("<all in='\"foo\"'>");
    })
    beforeeach(() =&gt; {
        console.log("<each in='\"foo\"'>");
    })
    afterall(() =&gt; {
        console.log("</each></all><!-- in=\"foo\" -->");
    })
    aftereach(() =&gt; {
        console.log("  <!-- in=\"foo\" -->");
    })

    test("testfoo", () =&gt; {
        console.log("<test in='\"foo\"' id='\"testfoo\"'></test>");
    })

    console.log("</describe><!-- id=\"foo\" -->");
})

describe("bar", () =&gt; {
    describe("barinner", () =&gt; {
        console.log("<describe id='\"barinner\"'>");

        beforeall(() =&gt; {
            console.log("<all in='\"barinner\"'>");
        })
        beforeeach(() =&gt; {
            console.log("<each in='\"barinner\"'>");
        })
        afterall(() =&gt; {
            console.log("</each></all><!-- in=\"barinner\" -->");
        })
        aftereach(() =&gt; {
            console.log(" <!-- in=\"barinner\" -->");
        })

        test("testbarinner", () =&gt; {
            console.log("<test in='\"barinner\"' id='\"testbarinner\"'></test>");
        })

        console.log("</describe><!-- id=\"barinner\" -->");
    })

    console.log("<describe id='\"bar\"'>");

    beforeall(() =&gt; {
        console.log("<all in='\"bar\"'>");
    })
    beforeeach(() =&gt; {
        console.log("<each in='\"bar\"'>");
    })
    afterall(() =&gt; {
        console.log("</each></all><!-- in=\"bar\" -->");
    })
    aftereach(() =&gt; {
        console.log(" <!-- in=\"bar\" -->");
    })

    test("testbar", () =&gt; {
        console.log("<test in='\"bar\"' id='\"testbar\"'></test>");
    })
    test("testotherbar", () =&gt; {
        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>

这就是关于执行顺序的全部知识。