Nie ma domyślnej kolejności ładowania plików testowych przez Mocha.
Gdy Mocha skanuje katalog
aby znaleźć pliki to używa fs.readdirSync
. To wywołanie jest opakowaniem wokół readdir(3)
, co samo w sobie nie gwarantuje porządku. Teraz, ze względu na dziwactwo wdrożeniowe
wyjście fs.readdir
i fs.readdirSync
jest posortowany w systemie Linux (i prawdopodobnie ogólnie w systemach POSIX), ale nie w systemie Windows . Co więcej, możliwe jest, że posortowane zachowanie w systemie Linux może zostać ostatecznie usunięte, ponieważ dokumentacja mówi fs.readdir
to po prostu readdir(3)
a ten ostatni nie gwarantuje porządku. Można argumentować, że zachowanie zaobserwowane w systemie Linux jest błędem (patrz problem, do którego połączyłem się powyżej).
Zauważ, że istnieje --sort
opcja, która posortuje pliki po ich znalezieniu przez Mocha. Ale to jest domyślnie wyłączone.
Obserwowane zachowanie można wytłumaczyć nie tylko kolejnością ładowania, ale także kolejnością wykonania . Oto, co się dzieje:
-
Mocha ładuje pliki testowe i wykonuje je. Tak więc wszystko, co znajduje się na najwyższym poziomie pliku, jest wykonywane od razu . Oznacza to, że kod w
test_helper.js
wykonuje od razu. Każde wywołanieopisu
natychmiast wykonuje swoje wywołanie zwrotne. Jednak wzywa doto
zapisz test do późniejszego wykonania. Mocha odkrywa Twoje testy podczas wykonywania tego, ale nie wykonywania je od razu. -
Po wykonaniu wszystkich plików Mocha rozpoczyna testy. Do tego czasu kod w
test_helper.js
już został uruchomiony, a Twój test korzysta z utworzonego połączenia.
Poważne ostrzeżenie Połączenie z bazą danych jest operacją asynchroniczną i obecnie nic nie gwarantuje, że operacja asynchroniczna w test_helper.js
zakończy się przed rozpoczęciem testów. To, że teraz działa dobrze, to tylko szczęście.
Gdybym to był ja, umieściłbym tworzenie połączenia w globalnym asynchronicznym przed
hak. (globalny przed
hook pojawiający się w dowolnym pliku testowym zostanie wykonany przed jakimkolwiek testem, nawet testami, które pojawiają się w innych plikach. ) Lub użyłbym --delay
i jawnie wywołaj run()
aby uruchomić pakiet po zagwarantowaniu nawiązania połączenia.