web-dev-qa-db-ja.com

`before()`と `beforeEach()`の違いは何ですか?

Mochabefore()beforeEach()の違いは何ですか? (after()afterEach()についても同じ質問です。)

before()describe()ブロックごとに1回実行され、beforeEach()はテストごとに1回実行されると想定しています(it()ブロック)。本当?

そして、いつ他のものを使用することを選択しますか?

74
ericsoco

before()は、allのテストがdescribeの前に1回実行されます
after()は、allのテストがdescribeの後に1回実行されます
beforeEach()は、eachdescribeでテストする前に実行されます
afterEach()describeeachテストの後に実行されます

どちらを使用するかは、実際のテストによって異なります。

さて、長い説明のために。これに対してmocha -R minを実行すると:

describe("top", function () {
    before(function () {
        console.log("top before");
    });
    after(function () {
        console.log("top after");
    });
    beforeEach(function () {
        console.log("top beforeEach");
    });
    afterEach(function () {
        console.log("top afterEach");
    });
    it("test1", function () {
        console.log("top test1");
    });
    describe("sublevel", function() {
        before(function () {
            console.log("sublevel before");
        });
        after(function () {
            console.log("sublevel after");
        });
        beforeEach(function () {
            console.log("sublevel beforeEach");
        });
        afterEach(function () {
            console.log("sublevel afterEach");
        });
        it("test1", function () {
            console.log("sublevel test1");
        });
        it("test2", function () {
            console.log("sublevel test2");
        });
    });
    it("test2", function () {
        console.log("top test2");
    });
});

次のようなものが表示されます(関連のない出力は省略しました)。

top before
top beforeEach
top test1
top afterEach
top beforeEach
top test2
top afterEach
sublevel before
top beforeEach
sublevel beforeEach
sublevel test1
sublevel afterEach
top afterEach
top beforeEach
sublevel beforeEach
sublevel test2
sublevel afterEach
top afterEach
sublevel after
top after

サブレベルでの各テストの前後に実行されるものを見ると驚くかもしれないのは、bothトップレベルとサブレベルでのbeforeEachコールバックが呼び出されることです。 afterEachも同じです。

シーケンスsublevel beforetop beforeEachsublevel beforeEachにも驚かされる人もいます。彼らは、外側のスコープのすべてのフックが内側のスコープのすべてのフックよりも先に実行されるべきだと考えているため、top beforeEachsublevel beforesublevel beforeEachというシーケンスを期待しています。ただし、Mochaがフックを実行する順序は完全に理にかなっています。beforeフックはテストのグループのステージを設定するためのものであり、beforeEachテストは個々のテストごとです。 Mochaがテストを実行すると、それを含むbeforeに設定されたすべてのbeforeEachフックとdescribeフック、およびそのdescribeのすべての祖先テストに適用します。 Mochaは、最も外側のスコープから最も内側の各beforeフックと、最も外側のスコープから最も内側のすべてのbeforeEachフックを実行します。 ただし、適用されるすべてのbeforeフックは、beforeEachフックの前に実行されます。これは上記の順序を説明します。sublevel beforebeforeフックであるため、top beforeEachの前に実行されます。 afterafterEachを使用すると、同じロジックが適用されますが、順序が逆になります。適用されるすべてのafterEachフックは、afterフックの前に実行されます。

また、最上位のitdescribe呼び出しに関連して、describe呼び出しの順序をMochaが気にしていないことに注意してください。 top test1top test2、およびthenを実行します。ただし、指定した順序はtop test1、サブレベルテスト、top test2です。 。

beforebeforeEachなどの中で使用するものは、テストの詳細に依存します。モックオブジェクトまたはデータ構造をセットアップする必要があり、このオブジェクトまたは構造canが単一のdescribe内のすべてのテストで再利用される場合、beforeを使用してそれを設定し、afterを破棄します。これは、構造に対して読み取り専用テストを実行している場合に該当する可能性があります。すべてのテストがそれを読み取るだけである場合、何度も何度も作成する必要はありません。 describeの各テストがnew構造のコピーを必要とする場合、各テストはmodifying構造であるため、beforeEachを使用してテストごとに構造を新たに作成し、きれいに分解する必要がある場合はafterEachを作成します。これにより、テストの分離が保証されます。各テストは既知の状態から開始され、成功する前のテストの有無に依存しません。

158
Louis