2015-09-18 12 views
21

Wpadłem ostatnio na problem, którego nie potrafię wyjaśnić. Mam dużo kodu w tych testach, więc mam zamiar zrobić mój najlepszy uchwycić ideę tutajMocha beforeEach vs before execution

mam testy, które wyglądać tak:

describe('main page', function(){ 
    beforeEach(function(done){ 
    addUserToMongoDb(done); // #1 
    }); 

    afterEach(function(done){ 
    removeUserFromMongoDb(done); 
    }); 

    context('login', function(){ 
    it('should log the user in, function(){ 
     logUserIn(user_email); // #2 - This line requires the user from the beforeEach 
    }); 
    }); 

    context('preferences', function(){ 
    before(function(done){ //#3 
     logUserInBeforeTest(user_email); 
    }); 

    it('should show the preferences', function(){ 
     doCheckPreferences(); // #4 
    }); 
    }); 
}); 

Problem znaczy beforeEach przez #1 działa poprawnie . Widzę, jak to się dzieje na DB i testy w passie #2.

Jednak testy w kontekście preferencji pod adresem #4 nie powiodły się, ponieważ nie można znaleźć użytkownika, który mógłby go zalogować pod numerem #3.

Wygląda na to, że kontekst before jest wykonywany przed opisem beforeEach, co powoduje ich niepowodzenie. Jeśli przeniesię logUserIn do bloku it, to działa dobrze.

Co może spowodować?

+1

Nie można wytłumaczyć, dlaczego * "Wygląda na to, że poprzedni kontekst jest wykonywany przed opisem beforeEach" *, ale czy w tym momencie nie powinieneś wykonywać 'done'? –

+0

Przed jest przed całym blokiem, przed każdym przed każdym testem. –

+1

@StevenScott Więc to dlaczego. Opis beforeEach działa wcześniej po kontekście. Szkoda, że ​​dokumentacja nie stała się bardziej oczywista. – Tomo

Odpowiedz

35

Biegacz testowy firmy Mocha wyjaśnia tę funkcję jako najlepszą w modelu Hooks section of the Mocha Test Runner.

W sekcji Hooks:

describe('hooks', function() { 

    before(function() { 
     // runs before all tests in this block 
    }); 

    after(function() { 
     // runs after all tests in this block 
    }); 

    beforeEach(function() { 
     // runs before each test in this block 
    }); 

    afterEach(function() { 
     // runs after each test in this block 
    }); 

    // test cases 
}); 

Można zagnieździć te procedury w ramach innych opisuje bloki, które mogą mieć także przed/beforeEach rutyny.

15

Znalazłem podobny problem. Dokumentacja wprowadza w błąd, ponieważ "przed tym blokiem" oznacza (przynajmniej dla mnie) "przed tą sekcją opisującą". Tymczasem oznacza to "przed każdą sekcją opisową". Sprawdź ten przykład:

describe('outer describe', function() { 
    beforeEach(function() { 
     console.log('outer describe - beforeEach'); 
    }); 

    describe('inner describe 1', function() { 
     before(function() { 
      console.log('inner describe 1 - before'); 
     }); 

    describe('inner describe 2', function() { 
     beforeEach(function() { 
      console.log('inner describe 2 - beforeEach'); 
     }); 
}); 

// output will be: 
// inner describe 1 - before 
// outer describe - beforeEach 
// inner describe 2 - beforeEach 

Wydaje się, że nie ma znaczenia, gdzie w hierarchii umieścić before - to będzie działać zanim opisać, a nie przed jego zawierający opisać.

+0

Pomyśl o tym jako "przed każdym blokiem". Oznacza to przed każdym testem i przed każdym opisem. –

3

Powód zamieszania leży w dokumentacji mokki. można znaleźć w mocha:

Testy mogą pojawić się przed, po lub przeplatane ze swoimi hakami. Haczyki będą działały w kolejności, w jakiej zostały zdefiniowane, w zależności od potrzeb; all before() hooks run (once), następnie any beforeEach() hookuje, testuje, dowolne haki AfterEach(), a na końcu hakuje() (raz).

komentowane haki before i beforeEach są wykonywane tuż przed całości lub każdy it odpowiednio - nie ma sposobu, aby go wykonać przed opisać sekcję.

Tutaj możesz find odpowiedzieć # 1 wkład do głównego oddziału mokki na pomysł dodaj coś w stylu haczyka beforeDescribe.

Myślę, że powinieneś spojrzeć na --delay mocha option.