Setup und Teardown
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Beim Schreiben von Tests gibt es oft Vorbereitungsarbeiten, die vor dem Testlauf ausgeführt werden müssen, sowie Aufräumarbeiten, die danach erledigt werden müssen. Jest bietet Hilfsfunktionen, um dies zu bewältigen.
Wiederholende Vorbereitung
Wenn bestimmte Arbeiten für mehrere Tests wiederholt werden müssen, können Sie beforeEach- und afterEach-Hooks verwenden.
Angenommen, mehrere Tests interagieren mit einer Städtedatenbank. Sie benötigen eine Methode initializeCityDatabase(), die vor jedem Test aufgerufen werden muss, und eine Methode clearCityDatabase(), die nach jedem Test aufgerufen werden muss. Das lässt sich so umsetzen:
beforeEach(() => {
initializeCityDatabase();
});
afterEach(() => {
clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
beforeEach und afterEach können asynchronen Code auf dieselbe Weise verarbeiten wie Tests asynchronen Code verarbeiten - sie können entweder einen done-Parameter entgegennehmen oder ein Promise zurückgeben. Wenn initializeCityDatabase() beispielsweise ein Promise zurückgibt, das bei erfolgreicher Initialisierung der Datenbank aufgelöst wird, sollten wir dieses Promise zurückgeben:
beforeEach(() => {
return initializeCityDatabase();
});
Einmalige Vorbereitung
In manchen Fällen ist eine Vorbereitung nur einmal am Anfang einer Datei nötig. Dies kann besonders lästig sein, wenn die Vorbereitung asynchron ist und nicht inline erfolgen kann. Jest bietet beforeAll- und afterAll-Hooks für solche Situationen.
Wenn sowohl initializeCityDatabase() als auch clearCityDatabase() Promises zurückgeben und die Städtedatenbank zwischen Tests wiederverwendet werden kann, könnten wir unseren Testcode so anpassen:
beforeAll(() => {
return initializeCityDatabase();
});
afterAll(() => {
return clearCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
Geltungsbereich
Die obersten before*- und after*-Hooks gelten für alle Tests in einer Datei. Die innerhalb eines describe-Blocks deklarierten Hooks gelten nur für die Tests innerhalb dieses describe-Blocks.
Angenommen, wir haben neben einer Städtedatenbank auch eine Lebensmitteldatenbank. Wir könnten für verschiedene Tests unterschiedliche Vorbereitungen treffen:
// Applies to all tests in this file
beforeEach(() => {
return initializeCityDatabase();
});
test('city database has Vienna', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('city database has San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
describe('matching cities to foods', () => {
// Applies only to tests in this describe block
beforeEach(() => {
return initializeFoodDatabase();
});
test('Vienna <3 veal', () => {
expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
});
test('San Juan <3 plantains', () => {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});
Beachten Sie, dass der oberste beforeEach-Hook vor dem beforeEach-Hook im describe-Block ausgeführt wird. Dies verdeutlicht die Ausführungsreihenfolge aller Hooks.
beforeAll(() => console.log('1 - beforeAll'));
afterAll(() => console.log('1 - afterAll'));
beforeEach(() => console.log('1 - beforeEach'));
afterEach(() => console.log('1 - afterEach'));
test('', () => console.log('1 - test'));
describe('Scoped / Nested block', () => {
beforeAll(() => console.log('2 - beforeAll'));
afterAll(() => console.log('2 - afterAll'));
beforeEach(() => console.log('2 - beforeEach'));
afterEach(() => console.log('2 - afterEach'));
test('', () => console.log('2 - test'));
});
// 1 - beforeAll
// 1 - beforeEach
// 1 - test
// 1 - afterEach
// 2 - beforeAll
// 1 - beforeEach
// 2 - beforeEach
// 2 - test
// 2 - afterEach
// 1 - afterEach
// 2 - afterAll
// 1 - afterAll
Ausführungsreihenfolge
Jest führt alle describe-Handler in einer Testdatei aus, bevor es einen der eigentlichen Tests ausführt. Dies ist ein weiterer Grund, Vorbereitungs- und Aufräumarbeiten in before*- und after*-Handlern statt innerhalb von describe-Blöcken durchzuführen. Nach Abschluss der describe-Blöcke führt Jest standardmäßig alle Tests seriell in der Reihenfolge ihrer Erfassung aus und wartet jeweils auf Abschluss und Bereinigung.
Betrachten Sie diese illustrative Testdatei und ihre Ausgabe:
describe('describe outer', () => {
console.log('describe outer-a');
describe('describe inner 1', () => {
console.log('describe inner 1');
test('test 1', () => console.log('test 1'));
});
console.log('describe outer-b');
test('test 2', () => console.log('test 2'));
describe('describe inner 2', () => {
console.log('describe inner 2');
test('test 3', () => console.log('test 3'));
});
console.log('describe outer-c');
});
// describe outer-a
// describe inner 1
// describe outer-b
// describe inner 2
// describe outer-c
// test 1
// test 2
// test 3
Ähnlich wie describe- und test-Blöcke ruft Jest before*- und after*-Hooks in ihrer Deklarationsreihenfolge auf. Beachten Sie, dass after*-Hooks des umschließenden Bereichs zuerst aufgerufen werden. So können Sie beispielsweise voneinander abhängige Ressourcen einrichten und abbauen:
beforeEach(() => console.log('connection setup'));
beforeEach(() => console.log('database setup'));
afterEach(() => console.log('database teardown'));
afterEach(() => console.log('connection teardown'));
test('test 1', () => console.log('test 1'));
describe('extra', () => {
beforeEach(() => console.log('extra database setup'));
afterEach(() => console.log('extra database teardown'));
test('test 2', () => console.log('test 2'));
});
// connection setup
// database setup
// test 1
// database teardown
// connection teardown
// connection setup
// database setup
// extra database setup
// test 2
// extra database teardown
// database teardown
// connection teardown
Wenn Sie den jasmine2-Testrunner verwenden, beachten Sie, dass dieser after*-Hooks in umgekehrter Deklarationsreihenfolge aufruft. Für identische Ausgabe sollte das obige Beispiel wie folgt angepasst werden:
beforeEach(() => console.log('connection setup'));
+ afterEach(() => console.log('connection teardown'));
beforeEach(() => console.log('database setup'));
+ afterEach(() => console.log('database teardown'));
- afterEach(() => console.log('database teardown'));
- afterEach(() => console.log('connection teardown'));
// ...
Allgemeine Empfehlungen
Wenn ein Test fehlschlägt, sollten Sie zunächst prüfen, ob der Test auch dann fehlschlägt, wenn er allein ausgeführt wird. Um nur einen Test mit Jest auszuführen, ändern Sie den test-Befehl vorübergehend in test.only:
test.only('this will be the only test that runs', () => {
expect(true).toBe(false);
});
test('this test will not run', () => {
expect('A').toBe('A');
});
Wenn ein Test häufig fehlschlägt, wenn er als Teil einer größeren Testsuite läuft, aber nicht, wenn er allein ausgeführt wird, dann ist es sehr wahrscheinlich, dass etwas von einem anderen Test diesen beeinflusst. Oft können Sie das Problem beheben, indem Sie gemeinsame Zustände mit beforeEach zurücksetzen. Wenn Sie unsicher sind, ob ein gemeinsamer Zustand verändert wird, können Sie auch eine beforeEach-Funktion verwenden, die Daten protokolliert.