寫測試的時候你經(jīng)常需要在運行測試前做一些準備工作,和在運行測試后進行一些整理工作。 Jest 提供輔助函數(shù)來處理這個問題。
如果你有一些要為多次測試重復(fù)設(shè)置的工作,你可以使用 ?beforeEach
?和 ?afterEach
?。
例如,我們考慮一些與城市信息數(shù)據(jù)庫進行交互的測試。 你必須在每個測試之前調(diào)用方法 ?initializeCityDatabase()
?,同時必須在每個測試后,調(diào)用方法 ?clearCityDatabase()
?。 你可以這樣做:
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
?和 ?afterEach
?能夠通過與 異步代碼測試 相同的方式處理異步代碼 — — 他們可以采取 ?done
?參數(shù)或返回一個 promise。 例如,如果 ?initializeCityDatabase()
?返回解決數(shù)據(jù)庫初始化時的 promise ,我們會想返回這一 promise︰
beforeEach(() => {
return initializeCityDatabase();
});
在某些情況下,你只需要在文件的開頭做一次設(shè)置。當設(shè)置是異步的時,這可能會特別麻煩,因此你就不能內(nèi)聯(lián)執(zhí)行。Jest 提供 ?beforeAll
?和 ?afterAll
?處理這種情況。
例如,如果 ?initializeCityDatabase
?和 ?clearCityDatabase
?都返回了 promise ,城市數(shù)據(jù)庫可以在測試中重用,我們就能把我們的測試代碼改成這樣:
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();
});
默認情況下,?before
?和 ?after
?的塊可以應(yīng)用到文件中的每個測試。 此外可以通過 ?describe
?塊來將測試分組。 當 ?before
?和 ?after
?的塊在 ?describe
?塊內(nèi)部時,則其只適用于該 ?describe
?塊內(nèi)的測試。
例如,我們不僅有一個城市數(shù)據(jù)庫,而且還有一個食品數(shù)據(jù)庫。 我們可以為不同的測試進行不同的設(shè)置:
// 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);
});
});
注意,頂級的 ?beforeEach
?在 ?describe
?塊級的 ?beforeEach
?之前被執(zhí)行。 這可能有助于說明所有鉤子的執(zhí)行順序。
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
Jest 會在所有真正的測試開始之前執(zhí)行測試文件里所有的 describe 處理程序(handlers)。 這是在 ?before*
?和 ?after*
?處理程序里面 (而不是在 describe 塊中)進行準備工作和整理工作的另一個原因。 默認情況下,當 describe 塊運行完后,Jest 會按照 test 出現(xiàn)的順序(譯者注:原文是in the order they were encountered in the collection phase)依次運行所有測試,,等待每一個測試完成并整理好,然后才繼續(xù)往下走。
考慮以下示例測試文件和輸出:
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
如果測試失敗,第一件要檢查的事就是,當僅運行這條測試時,它是否仍然失敗。 要使用Jest僅運行一個?test
?,請將該測試命令臨時更改為?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');
});
如果你有一個測試,當它作為一個更大的用例中的一部分時,經(jīng)常運行失敗,但是當你單獨運行它時,并不會失敗,所以最好考慮其他測試對這個測試的影響。 通??梢酝ㄟ^修改 ?beforeEach
?來清除一些共享的狀態(tài)來修復(fù)這種問題。 如果不確定是否正在修改某些共享狀態(tài),也可以嘗試使用?beforeEach
?記錄數(shù)據(jù)。
更多建議: