Configuration et nettoyage
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Lorsque vous écrivez des tests, vous avez souvent besoin d'effectuer des tâches de préparation avant leur exécution et des opérations de finalisation après leur exécution. Jest propose des fonctions utilitaires pour gérer cela.
Configuration répétitive
Si vous avez des opérations à répéter pour plusieurs tests, utilisez les hooks beforeEach et afterEach.
Par exemple, imaginons que plusieurs tests interagissent avec une base de données de villes. Vous disposez d'une méthode initializeCityDatabase() à appeler avant chaque test et d'une méthode clearCityDatabase() à appeler après chaque test. Vous pouvez procéder ainsi :
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 et afterEach gèrent le code asynchrone de la même manière que les tests gèrent le code asynchrone : ils peuvent accepter un paramètre done ou renvoyer une promesse. Par exemple, si initializeCityDatabase() renvoie une promesse résolue après l'initialisation de la base, nous devrions renvoyer cette promesse :
beforeEach(() => {
return initializeCityDatabase();
});
Configuration unique
Dans certains cas, une configuration unique en début de fichier suffit. Ceci peut être particulièrement problématique quand la configuration est asynchrone et ne peut être faite directement. Jest propose les hooks beforeAll et afterAll pour ces situations.
Par exemple, si initializeCityDatabase() et clearCityDatabase() renvoient toutes deux des promesses et que la base de donn ées peut être réutilisée entre les tests, nous pourrions modifier notre code ainsi :
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();
});
Portée des hooks
Les hooks before* et after* de niveau supérieur s'appliquent à tous les tests d'un fichier. Ceux déclarés dans un bloc describe ne s'appliquent qu'aux tests de ce bloc describe.
Par exemple, imaginons que nous ayons une base de données de villes et une autre d'aliments. Nous pourrions avoir différentes configurations :
// 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);
});
});
Notez que le beforeEach de niveau supérieur s'exécute 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
Jest exécute tous les gestionnaires describe d'un fichier de test avant tout test réel. C'est une raison supplémentaire d'effectuer configuration et nettoyage dans les handlers before* et after* plutôt que dans les blocs describe. Une fois les blocs describe terminés, Jest exécute par défaut tous les tests séquentiellement dans l'ordre de leur découverte, attendant que chacun se termine et soit nettoyé avant de passer au suivant.
Considérez ce fichier de test illustratif et sa sortie :
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
Comme pour les blocs describe et test, Jest appelle les hooks before* et after* dans l'ordre de déclaration. Notez que les hooks after* de la portée englobante sont appelés en premier. Par exemple, voici comment configurer et nettoyer des ressources interdépendantes :
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
Si vous utilisez le runner de test jasmine2, notez qu'il appelle les hooks after* dans l'ordre inverse de déclaration. Pour obtenir une sortie identique, modifiez l'exemple précédent ainsi :
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'));
// ...
Recommandations générales
Si un test échoue, vérifiez d'abord s'il échoue lorsqu'il est exécuté seul. Pour n'exécuter qu'un seul test avec Jest, remplacez temporairement test par 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');
});
Si vous avez un test qui échoue fréquemment lorsqu'il est exécuté dans une suite plus large, mais qui fonctionne correctement en isolation, il est fort probable qu'un autre test interfère avec celui-ci. Vous pouvez souvent résoudre ce problème en nettoyant l'état partagé avec beforeEach. Si vous n'êtes pas sûr qu'un état partagé soit modifié, vous pouvez également utiliser un beforeEach pour journaliser les données.