Vai al contenuto principale
{ "message": "Versione: 30.0", "description": "" }

Configurazione e Pulizia

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Spesso durante la scrittura dei test è necessario eseguire alcune operazioni preliminari prima dell'esecuzione dei test e operazioni conclusive dopo il loro completamento. Jest offre funzioni helper per gestire queste situazioni.

Configurazione Ripetitiva

Se devi ripetere alcune operazioni per molti test, puoi utilizzare gli hook beforeEach e afterEach.

Ad esempio, supponiamo che diversi test interagiscano con un database di città. Hai un metodo initializeCityDatabase() che deve essere chiamato prima di ogni test e un metodo clearCityDatabase() da chiamare dopo ogni test. Puoi gestirlo così:

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 e afterEach possono gestire codice asincrono nello stesso modo in cui i test gestiscono codice asincrono - possono accettare un parametro done o restituire una promise. Ad esempio, se initializeCityDatabase() restituisse una promise che si risolve quando il database è inizializzato, dovremmo restituire quella promise:

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

Configurazione Singola

In alcuni casi, è sufficiente eseguire la configurazione una sola volta all'inizio del file. Questo può risultare particolarmente problematico quando la configurazione è asincrona e non può essere eseguita inline. Jest offre gli hook beforeAll e afterAll per gestire questa situazione.

Ad esempio, se sia initializeCityDatabase() che clearCityDatabase() restituissero promise e il database delle città potesse essere riutilizzato tra i test, potremmo modificare il codice come segue:

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();
});

Ambito di Applicazione

Gli hook before* e after* a livello superiore si applicano a tutti i test di un file. Gli hook dichiarati all'interno di un blocco describe si applicano solo ai test contenuti in quel blocco describe.

Ad esempio, supponiamo di avere oltre a un database di città anche un database di cibi. Potremmo definire configurazioni diverse per test diversi:

// 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);
});
});

Nota che il beforeEach a livello superiore viene eseguito prima del beforeEach interno al blocco describe. Può essere utile visualizzare l'ordine di esecuzione di tutti gli hook.

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

Ordine di Esecuzione

Jest esegue tutti i gestori describe in un file di test prima di eseguire qualsiasi test effettivo. Questo è un ulteriore motivo per eseguire configurazione e pulizia all'interno degli handler before* e after* anziché nei blocchi describe. Una volta completati i blocchi describe, Jest esegue tutti i test in modo seriale nell'ordine in cui sono stati rilevati durante la fase di raccolta, attendendo il completamento e la pulizia di ciascuno prima di passare al successivo.

Considera il seguente file di test illustrativo e il suo output:

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

Proprio come per i blocchi describe e test, Jest chiama gli hook before* e after* nell'ordine di dichiarazione. Nota che gli hook after* dell'ambito più esterno vengono chiamati per primi. Ad esempio, ecco come puoi configurare e smantellare risorse interdipendenti:

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
nota

Se stai utilizzando il test runner jasmine2, tieni presente che chiama gli hook after* nell'ordine inverso di dichiarazione. Per ottenere un output identico, l'esempio precedente dovrebbe essere modificato così:

  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'));

// ...

Consigli Generali

Se un test fallisce, una delle prime verifiche dovrebbe essere se il test fallisce quando viene eseguito da solo. Per eseguire un singolo test con Jest, modifica temporaneamente il comando test 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');
});

Se hai un test che spesso fallisce quando viene eseguito come parte di una suite più ampia, ma non fallisce quando lo esegui da solo, è molto probabile che qualcosa proveniente da un altro test stia interferendo con questo. Puoi spesso risolvere il problema ripulendo alcuni stati condivisi usando beforeEach. Se non sei sicuro che uno stato condiviso venga modificato, puoi anche provare un beforeEach che registri i dati.