Setup and Teardown
A menudo cuando escribes las pruebas tienes algo de trabajo de preparación que necesita pasar antes de correr las pruebas, y tienes trabajo de finalización que debe pasar luego de correr las pruebas. Jest provee funciones de ayuda para manejar esto.
Repitiendo "preparación" para muchas pruebas
Si tienes algo de trabajo que necesitas hacer repetidamente para muchas pruebas, puedes usar beforeEach
y afterEach
.
Por ejemplo, digamos que varias pruebas interactúan con la base de datos de ciudades. Tienes un método initializeCityDatabase()
que debe ser llamada antes de cada prueba, y un método clearCityDatabase()
que debe ser llamado luego de cada prueba. Puedes hacer esto con:
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
y afterEach
pueden manejar código asíncrono en el mismo modo que las pruebas manejan código asíncrono - ambos pueden tomar done
como parámetro o devolver una promesa. Por ejemplo, si initializeCityDatabase()
devuelve una promesa que es resuelta cuando la base de datos es inicializada, nos gustaría que devuelva esa promesa:
beforeEach(() => {
return initializeCityDatabase();
});
Preparación de una vez
En algunos casos, solo necesitarás realizar la preparación una sola vez, al principio del archivo. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest proporciona beforeAll
y afterAll
para manejar esta situación.
Por ejemplo, si initializeCityDatabase
y clearCityDatabase
devolvieron promesas, y la base de datos de de ciudades podría ser reutilizado entre pruebas, podríamos cambiar nuestro código de prueba para:
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();
});
Alcance
Por defecto, los bloques before
y after
aplicarán a cada prueba en un archivo. También puede agrupar pruebas usando un bloque de describe
. Cuando están dentro de un bloque describe
, los bloques before
y after
sólo se aplican a las pruebas dentro de ese bloque describe
.
Por ejemplo, supongamos que hemos tenido no sólo una base de datos de ciudades, sino también una base de datos de alimentos. Podríamos hacer una configuración diferente para diferentes pruebas:
// 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 sausage', () => {
expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
});
test('San Juan <3 plantains', () => {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});
Note that the top-level beforeEach
is executed before the beforeEach
inside the describe
block. It may help to illustrate the order of execution of all 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
Orden de ejecución de descripción y bloques de pruebas
Jest executes all describe handlers in a test file before it executes any of the actual tests. This is another reason to do setup and teardown inside before*
and after*
handlers rather than inside the describe blocks. Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on.
Considere el siguiente archivo de prueba ilustrativa y salida:
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
Aviso General
Si una prueba falla, una de las primeras cosas a revisar debería ser si la prueba falla cuando se corre solo esa prueba. To run only one test with Jest, temporarily change that test
command to a 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 tienes una prueba que a menudo falla cuando es una parte de una ejecución de una larga suite, pero no falla cuando la corres sola, es una buena apuesta que algo de otra prueba diferente está interfiriendo con esta. A menudo puedes arreglar esto limpiando algo de estados compartidos con beforeEach
. If you're not sure whether some shared state is being modified, you can also try a beforeEach
that logs data.