Quelle est la différence entre «before ()» et «beforeEach ()»?

90

Quelle est précisément la différence entre Mocha de before()et beforeEach()? (Même question pour after()et afterEach().)

Je suppose qu'il before()s'exécute une fois par describe()bloc et beforeEach()une fois par test ( it()bloc). Est-ce vrai?

Et quand choisirais-je d'utiliser l'un plutôt que l'autre?

ericsoco
la source

Réponses:

188

before()est exécuté une fois avant que tous les tests de a describe
after()   soient exécutés une fois après que tous les tests de a describe
beforeEach()soient exécutés avant que chaque test de a ne describe
afterEach()   soit exécuté après chaque test d'undescribe

Celui que vous souhaitez utiliser dépend de votre test réel.

Maintenant, pour la longue explication. Si vous exécutez mocha -R minsur ceci:

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");
    });
});

Vous verrez quelque chose comme (j'ai omis la sortie qui n'est pas pertinente):

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

La seule chose qui peut surprendre si vous regardez ce qui exécute avant et après chacun des essais au niveau inférieur est que les deux les beforeEachcallbacks au niveau supérieur et au niveau inférieur sont appelés. Même chose pour le afterEach.

Certains sont également surpris par la séquence sublevel before, top beforeEach, sublevel beforeEach. Ils pensent que tous les crochets dans un champ extérieur doivent exécuter avant tous les crochets dans une portée intérieure, donc ils attendent la séquence: top beforeEach, sublevel before, sublevel beforeEach. Cependant, l'ordre dans lequel Mocha exécute les hooks a tout son sens: un beforehook est destiné à préparer le terrain pour un groupe de tests, alors qu'un beforeEachtest est pour chaque test individuel. Lorsque Mocha exécute un test, tous les beforeet les beforeEachhooks qui ont été définis dans le describequi le contient, et tous les ancêtres de celui-ci describes'appliquent au test. Mocha exécutera chaque beforecrochet de la portée la plus externe à la plus interne, et tous les beforeEachhooks de la portée la plus externe à la plus interne. pourtant, tous les beforehooks qui s'appliquent sont exécutés avant tout beforeEachhook. Ceci explique l'ordre ci-dessus: sublevel befores'exécute avant top beforeEachcar c'est un beforehook. Et avec afteret afterEach, la même logique s'applique mais l'ordre est inversé: tous les afterEachhooks qui s'appliquent sont exécutés avant tout afterhook.

Notez également que Mocha ne se soucie pas de la façon dont j'ai ordonné mes itappels par rapport à l' describeappel au niveau supérieur describe. Il exécute top test1, top test2et puis les tests, sous - niveau même si l'ordre donné était je top test1, puis les tests de sublevel puis top test2.

Ce que vous voulez utiliser parmi before, beforeEachetc. dépend vraiment des spécificités de vos tests. Si vous avez besoin de configurer un objet ou une structure de données fictif et que cet objet ou cette structure peut être réutilisé par tous les tests en un seul describe, vous pouvez l'utiliser beforepour le configurer et afterle démolir. Cela peut être le cas si vous effectuez des tests en lecture seule sur la structure. Si tous vos tests ne le lisent que, il n'est pas nécessaire de le créer encore et encore. Si chaque test dans vos describebesoins une nouvelle copie de la structure parce que chaque test modifie la structure, vous devez utiliser beforeEachpour créer la structure à nouveau pour chaque testafterEachsi vous devez le démolir proprement. Cela garantit l'isolement du test: chaque test commence à partir d'un état connu et ne dépend pas de la présence ou de l'absence d'un test précédent pour réussir.

Louis
la source
1
Super merci. Ma question portait en partie sur quoi et en partie pourquoi, cela cloue les deux, en particulier la distinction entre lecture / écriture.
ericsoco