Skip to main content
Version: 25.x

Inicialización y Finalización

Frecuentemente cuando escribes las pruebas tienes algo de trabajo de inicialización que necesita ejecutarse antes de correr las pruebas, y tienes trabajo de finalización que debe ejecutarse luego de correr las pruebas. Jest provee funciones para manejar esto.

Reutilizando la inicialización para varias 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();
});

Inicialización una vez antes de todos los tests

En algunos casos, solo necesitarás realizar la preparación una sola vez, al principio del archivo. Esto puede ser especialmente molesto cuando la inicialización es asíncrona, y no puede hacerse simplemente en una sola línea. 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

The top level before* and after* hooks apply to every test in a file. The hooks declared inside a describe block apply only to the tests within that describe block.

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 veal', () => {
expect(isValidCityFoodPair('Vienna', 'Wiener Schnitzel')).toBe(true);
});

test('San Juan <3 plantains', () => {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});

Ten en cuenta que el beforeEach de nivel superior será ejecutado antes del beforeEach dentro del describe. Puede ayudar a ilustrar el orden de ejecución de todos los 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 describe y bloques de tests

Jest ejecuta todos los manejadores de los describes en el archivo de tests antes que se ejecute alguno de los tests. Esta es otra razón para inicializar y desmontar en los before* y after* en vez de en los describe. Una vez que los describe están completos, por defecto Jest corre todas las pruebas en serie en el orden que fueron escritas en la fase de colección, esperando que cada una termine antes de avanzar.

Considere el siguiente archivo de prueba ilustrativa y su respectiva 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).toBe(true);
});
});

console.log('describe outer-b');

test('test 1', () => {
console.log('test for describe outer');
expect(true).toBe(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).toBe(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. Para correr un único test en Jest, cambie temporalmente test 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 veces falla cuando se ejecuta junto a toda la suite, pero no falla cuando la corres individualmente, es probable que no haya independencia entre los tests. A veces puedes arreglar esto limpiando estados compartidos con beforeEach. Si no estás seguro de que algun estado compartido se esté modificando, puedes probar un beforeEach que imprima los datos.