Próbuję połączyć wszystkie testy z wielu plików w jednym pliku, coś takiego:
describe('Controllers', function() {
describe('messages.js', function() {
require('./controllertests/messages').test(options);
})
describe('users.js', function() {
require('./controllertests/users').test(options);
})
})
Jestem prawie pewien, że nie jest to najlepszy sposób dołączania do testów, mam pewne trudności ze znalezieniem przykładów, jak to zrobić: s
node.js
unit-testing
mocha
coiso
źródło
źródło
.only()
, przydatna może być możliwośćdescribe.only()
uruchomienia całego katalogu testów. To właśnie mnie tu sprowadziło.Odpowiedzi:
Jeśli chcesz dołączyć wiele modułów do swojej
describe
hierarchii, tak jak robisz to w swoim pytaniu, to, co robisz, jest prawie tym , chyba że chcesz napisać niestandardowy program ładujący test dla Mocha. Napisanie niestandardowego modułu ładującego nie byłoby łatwiejsze ani nie uczyniłoby kodu bardziej przejrzystym niż to, co już masz.Oto przykład, jak zmieniłbym kilka rzeczy.
test
Podkatalogu w tym przykładzie jest organizowane jako:top.js
:function importTest(name, path) { describe(name, function () { require(path); }); } var common = require("./common"); describe("top", function () { beforeEach(function () { console.log("running something before each test"); }); importTest("a", './a/a'); importTest("b", './b/b'); after(function () { console.log("after all tests"); }); });
importTest
Funkcja jest po prostu pokazać, jak to będzie możliwe, aby poradzić sobie z powtórzeniem importowania wielu modułów bez konieczności ponownego wpisywania całydescribe(... require...
rzeczą każdym razem.common
Moduł ten służy do przechowywania, czego potrzebujesz do korzystania z wielu modułów zestawu testowego. W rzeczywistości nie używam go,top
ale w razie potrzeby można go tam użyć.W tym miejscu zauważę, że program
beforeEach
uruchomi swój kod przed każdym zarejestrowanym testem z informacją,it
czy pojawiają się one w programiedescribe
in,top
czy też pojawiają się w którymkolwiek z zaimportowanych modułów . Dzięki--recursive
temubeforeEach
kod musiałby zostać skopiowany do każdego modułu lub być może w każdym module byłby punktbeforeEach
zaczepienia, który wywołuje funkcję zaimportowaną ze wspólnego modułu.Ponadto
after
hak zostanie uruchomiony po wszystkich testach w pakiecie. Nie można tego powtórzyć za pomocą--recursive
. Jeśli użyjesz--recursive
i dodasz kodafter
do każdego modułu, będzie on wykonywany raz na moduł, a nie tylko raz na cały test.Wyświetlenia wszystkich testów pod pojedynczym
top
nagłówkiem nie można powielić za pomocą--recursive
. Z--recursive
każdego pliku może miećdescribe("top"
, ale to byłoby utworzyć nowytop
nagłówek dla każdego pliku.common.js
:var chai = require("chai"); var options = { foo: "foo" }; exports.options = options; exports.chai = chai; exports.assert = chai.assert;
Używanie modułu o
common
takiej nazwie jest czymś, co zrobiłem w niektórych moich zestawach testowych, aby uniknąć konieczności ciągłegorequire
wykonywania wielu rzeczy i utrzymywania globalnych zmiennych tylko do odczytu lub funkcji, które nie zachowują stanu. Wolę nie zanieczyszczaćglobal
obiektu, jak w odpowiedzi thgaskell, ponieważ ten obiekt jest naprawdę globalny i dostępny nawet w bibliotekach stron trzecich, który może ładować twój kod. To nie jest coś, co uważam za akceptowalne w moim kodzie.a/a.js
:var common = require("../common"); var options = common.options; var assert = common.assert; it("blah a", function () { console.log(options.foo); assert.isTrue(false); });
b/b.js
:it("blah b", function () {});
źródło
global
zakresu, używam tego w bibliotekach asercji, aby zachować czystość plików testowych. To nie tak, że nadpisujeszglobal.process
. Zmienne lokalne będą nadpisywać,global
chyba że inne biblioteki będą jawnie wywoływać,global.XYZ
co jest mało prawdopodobne. Trwa tylko przez czas trwania testów. Jeszcze mnie nie zranił, ale dam ci znać, kiedy ugryzie mnie w tyłek :)importTest
irequire('path')()
na przykład dzwonieniem ?importTest
funkcja jest tylko funkcją zwiększającą komfort. Ważną rzeczą, jaką robi, jest zawijanierequire
wywołania dodescribe
bloku. Ważne jest, abyrequire
wywołanie zostało zawinięte, wdescribe
przeciwnym razie moduły nie zostaną odizolowane w swoim własnym bloku, a wszelkie zaczepy ustawione przez importowany plik zostaną ustawione na niewłaściwy blok. GdybyimportTest
został zastąpiony bezpośrednim wywołaniemrequire
bez zawijaniadescribe
, wówczas modułya/a
ib/b
współdzieliłyby punkty zaczepienia. Na przykład,beforeEach
hak ustawiony wb/b
będzie również uruchamiany przed każdym testema/a
.Chociaż może to nie być bezpośrednio związane z pytaniem, odpowiedź, której szukałem, brzmiała:
Wykonuje wszystkie testy w podkatalogach folderu „test”. Schludny. Oszczędza konieczności utrzymywania listy testów, które chcę załadować i właściwie zawsze wszystko uruchamiam.
źródło
describe
bloków,describe
bloki obejmujące pliki,--recursive
nie zrobią tego. Ponieważ nie rozwiązuje to problemu PO, nie nazwałbym tego „najlepszym”.describe
blokidescribe
blokiem. Spójrz na pytanie. Blok „Kontrolery”describe
powinien obejmować testy./controllertests/messages.js
i./controllertests/users.js
. Uderzenie--recursive
w inwokację Mocha nie tworzy magiczniedescribe("Controllers"
bloku.describe
bloki - czego nauczyłem się od samego Dumbledore'a.Nic nie stoi na przeszkodzie, aby uruchomić wiele plików testowych. Ogólnie rzecz biorąc, każdy test nie powinien być zależny od wyników innego testu, więc udostępnianie zmiennych nie jest czymś, co chciałbyś robić.
Oto przykład, jak możesz zorganizować swoje pliki testowe.
Następnie w
mocha.opts
pliku upewnij się, że ustawiłeś--recursive
opcję.mocha.opts
Jeśli nie są wspólne moduły, które chcesz umieścić na wszystkich plikach, które można dodać do
common.js
pliku. Pliki w katalogu głównymtest
będą uruchamiane przed plikami w zagnieżdżonych katalogach.common.js
global.chai = require('chai'); global.assert = chai.assert; global.expect = chai.expect; chai.should(); chai.config.includeStack = true; process.env.NODE_ENV = 'test'; // Include common modules from your application that will be used among multiple test suites. global.myModule = require('../app/myModule');
źródło
describe('mytest', function() { /* ..... etc */ });
Wiem, że to stary post, ale chciałem się przyłączyć do tego, co było dla mnie dobrym rozwiązaniem, bardzo podobnym do metody zaproponowanej przez OP.
Projekt, nad którym pracuję, jest dobrze przetestowany, a testy wciąż się rozwijają. Skończyło się na tym,
require
że używam, ponieważ jest synchroniczny i dlatego nieco ułatwia komponowanie testów bez zbytniej zmiany architektury:// inside test/index.js describe('V1 ROUTES', () => { require('./controllers/claims.test'); require('./controllers/claimDocuments.test'); require('./controllers/claimPhotos.test'); require('./controllers/inspections.test'); require('./controllers/inspectionPhotos.test'); require('./controllers/versions.test'); require('./services/login.v1.test'); }); describe('V2 ROUTES', () => { require('./services/login.v2.test'); require('./services/dec-image.v2.test'); }); describe('V3 ROUTES', () => { require('./services/login.v3.test'); require('./services/getInspectionPhotosv3.test'); require('./services/getPolicyInfo.v3.test'); }); describe('ACTIONS', () => { require('./actions/notifications.test'); });
źródło
Miałem podobny problem, gdy miałem kilka testów dla klas z tej samej kategorii i chciałem je zgrupować, aby ułatwić przeglądanie ich w IDE. Wszystkie moje testy i kod korzystały już z modułów ES6 - nie chciałem przepisać ich wszystkich
require
tak, jak widziałem w innych przykładach.Rozwiązałem to
describe
, wyeksportowałem moje „grupowanie” , a następnie zaimportowałem je do plików testowych i programowo dodałem do zaimportowanychdescribe
. Skończyło się na stworzeniu metody pomocniczej, aby odciąć całą hydraulikę.W someCategory.spec.js
const someCategory= describe("someCategory", () => {}); // Use this just like a regular `describe` to create a child of this scope in another file export default function describeMember(skillName, testFn) { return describe(skillName, function configureContext() { // Make context a child of `someCategory` context function Context() {} Context.prototype = someCategory.ctx; this.ctx = new Context(); // Re-parent the suite created by `describe` above (defaults to root scope of file it was created in) this.parent.suites.pop(); someCategory.addSuite(this); // Invoke the fn now that we've properly set up the parent/context testFn.call(this); }); }
W poszczególnych testach:
import { default as describeCategoryMember } from './someCategory.spec'; describeCategoryMember('something', () => { describe('somethingElse', () => { ... }); it('a test', () => { ... }); })
źródło
describe( 'Running automation test, Please wait for all test to complete!'.red, function () { var run = require( './Test.js' ); for ( var i = 0; i < 2; i++ ) { run.badLogin(); run.loginLimited(); run.acceptJob(); run.drivingToJob(); run.arrivedAtJob(); run.towingJob(); run.arrivedDestination(); run.jobComplete(); run.restrictionLicensePlate(); run.newNodeMainMenu(); run.newNodeMainMenuToDrafts(); run.draftDelete(); run.resetAllData(); run.companyVehicle(); run.actionsScreenClockInOut(); run.mainMenuLogout(); run.loginAdmin(); run.actionsScreenLogout(); } } );
źródło
./Test.js
środku? Kto wie? Dla przypomnienia, obecnie jestem pierwszą osobą odpowiadającą w kategorii mokka . Znam Mokkę od podszewki, ale nie rozumiem tej odpowiedzi.