Aller au contenu principal
Version: 27.2

Préparation et nettoyage

Souvent, lorsque vous écrivez des tests, vous devez effectuer un travail de préparation avant l'exécution des tests, et un travail de nettoyage après l'exécution des tests. Jest fournit des fonctions d'aide pour gérer cela.

Répétition de la préparation pour de nombreux tests#

Si vous avez un travail à faire de manière répétitive pour de nombreux tests, vous pouvez utiliser beforeEach et afterEach.

Par exemple, disons que plusieurs tests interagissent avec une base de données de villes. Vous avez une méthode initializeCityDatabase() qui doit être appelée avant chacun de ces tests, et une méthode clearCityDatabase() qui doit être appelée après chacun de ces tests. Vous pouvez le faire avec :

beforeEach(() => {
initializeCityDatabase();
});
afterEach(() => {
clearCityDatabase();
});
test('la base de donnée possède Vienne', () => {
expect(isCity('Vienne')).toBeTruthy();
});
test('la base de donnée possède San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});

beforeEach et afterEach peuvent gérer le code asynchrone de la même manière que les tests peuvent gérer le code asynchrone - ils peuvent soit prendre un paramètre done, soit retourner une promesse. Par exemple, si initializeCityDatabase() renvoyait une promesse qui résolvait le moment où la base de données était initialisée, nous voudrions renvoyer cette promesse :

beforeEach(() => {
return initializeCityDatabase();
});

Préparation à usage unique#

Dans certains cas, vous n'avez besoin de faire la préparation qu'une seule fois, au début d'un fichier. Cela peut être particulièrement gênant lorsque la préparation est asynchrone, et que vous ne pouvez donc pas le faire en même temps. Jest fournit beforeAll et afterAll pour gérer cette situation.

Par exemple, si les deux initializeCityDatabase et clearCityDatabase retournent des promesses, et que la base de données de la ville peut être réutilisée entre les tests, nous pourrions modifier notre code de test en :

beforeAll(() => {
return initializeCityDatabase();
});
afterAll(() => {
return clearCityDatabase();
});
test('la base de donnée possède Vienne', () => {
expect(isCity('Vienna')).toBeTruthy();
});
test('la base de donnée possède San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});

Champ d'application#

Par défaut, les blocs before et after s'appliquent à chaque test d'un fichier. Vous pouvez également regrouper des tests à l'aide d'un bloc describe. Lorsqu'ils sont à l'intérieur d'un bloc describe, les blocs before et after ne s'appliquent qu'aux tests contenus dans ce bloc describe.

Par exemple, supposons que nous ayons non seulement une base de données sur les villes, mais aussi une base de données sur les aliments. Nous pourrions faire différentes configurations pour différents tests :

// S'applique à tous les tests de ce fichier
beforeEach(() => {
return initializeCityDatabase();
});
test('la base de donnée possède Vienne', () => {
expect(isCity('Vienne')).toBeTruthy();
});
test('la base de donnée possède San Juan', () => {
expect(isCity('San Juan')).toBeTruthy();
});
describe('correspondance entre les villes et les aliments', () => {
// S'applique uniquement aux tests de ce bloc describe
beforeEach(() => {
return initializeFoodDatabase();
});
test('Vienna <3 veau', () => {
expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
});
test('San Juan <3 bananes plantain', () => {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});

Notez que le beforeEach en haut du fichier est exécuté avant le beforeEach à l'intérieur du bloc describe. Il peut être utile d'illustrer l'ordre d'exécution de tous les 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

Ordre d'exécution des blocs describe et test#

Jest exécute tous les gestionnaires de describe dans un fichier de test avant qu'il n'exécute les tests proprement dits. C'est une autre raison de faire la préparation et le nettoyage à l'intérieur des gestionnaires before* et after* plutôt qu'à l'intérieur des blocs describe. Une fois les blocs de description terminés, par défaut, Jest exécute tous les tests en série dans l'ordre où ils ont été rencontrés dans la phase de collecte, en attendant que chacun d'eux se termine et soit nettoyé avant de passer à la suite.

Considérez le fichier de test illustratif suivant et la sortie :

describe('outer', () => {
console.log('describe outer-a');
describe('describe inner 1', () => {
console.log('describe inner 1');
test('test 1', () => {
console.log('test for describe inner 1');
expect(true).toEqual(true);
});
});
console.log('describe outer-b');
test('test 1', () => {
console.log('test for describe outer');
expect(true).toEqual(true);
});
describe('describe inner 2', () => {
console.log('describe inner 2');
test('test for describe inner 2', () => {
console.log('test for describe inner 2');
expect(false).toEqual(false);
});
});
console.log('describe outer-c');
});
// describe outer-a
// describe inner 1
// describe outer-b
// describe inner 2
// describe outer-c
// test for describe inner 1
// test for describe outer
// test for describe inner 2

Indications générales#

Si un test échoue, l'une des premières choses à vérifier : est-ce que le test échoue si c'est le seul test exécuté ? Pour exécuter un seul test avec Jest, changez temporairement cette commande test en une commande test.only :

test.only('ce sera le seul test exécuté', () => {
expect(true).toBe(false);
});
test('ce test ne s'exécutera pas', () => {
expect('A').toBe('A');
});

Si vous avez un test qui échoue souvent lorsqu'il est exécuté dans une série plus grande, mais qui n'échoue pas lorsque vous l'exécutez seul, il est fort probable que quelque chose d'un autre test interfère avec celui-ci. Vous pouvez souvent corriger cela en nettoyant certains états partagés avec beforeEach. Si vous n'êtes pas sûr qu'un état partagé soit modifié, vous pouvez également essayer un beforeEach qui journalise les données.