Dog foot print

[JEST] Setup and  Teardown 본문

TDD/JEST

[JEST] Setup and  Teardown

개 발자국 2021. 5. 18. 17:35

테스트를 진행 하기 전 테스트를 위한 설정을 해주거나, 테스트가 종료된 이후에 설정을 변경해야 할 때가 종종 있습니다. 제스트는 이를 위해서 유용한 함수들을 제공합니다.

Repeating Setup For Many Tests

만약 테스트가 종료된 후, 반복해야 할 코드가 존재할 때 `beforeEach` 또는 `afterEach`를 이용해 반복을 줄일 수 있습니다.

예를 들어, 테스트 마다 각 도시의 데이터베이스와 통신해야 한다고 가정하겠습니다. 개발자는 `initializeCityDatabase()`를 가지고 있고, 이는 테스트 전에 항상 호출 해야합니다. 또한 `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`는 test코드에서 비동기 코드를 작동시키는 것과 동일하게, callback으로 done이 전달 되며, promise를 반환할 수 있습니다. 위의 예제에서 만약 `initializeCityDatabase()`함수가 promise를 반환하는 경우, 이렇게 변경 시킬 수 있습니다.

 

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

 

One-Time setup

몇개의 경우에는 파일이 시작되면, 설정을 한번만 해줘야 하는 경우가 존재합니다. 이 경우, 매우 귀찮은 비동기 설정인 경우 일 수 있습니다. 그러니, 함수 내부에서 전부 작성하지 마세요. 제스트는 이런 문제를 해결하기 위해 `beforeAll`과 `afterAll` 함수를 제공합니다.

예를 들어, `initializeCityDatabase`와 `clearCityDatabase`가 프라미스를 반환할 때, 이 코드가 테스트간 계속 공유되는 설정 일 수 있습니다. 이런 경우, 다음과 같이 코드를 작성 할 수 있습니다.

 

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

 

Scoping

기본적으로 `before`와 `after` 블락은 파일 내부에 있는 모든 테스트에 적용 됩니다. 또한 개발자는, test를 `describe`블락으로 그루핑 할 수 있습니다. 이들이 `describe`블락에 존재 할 때, `before`와 `after`블락들은 이 함수가 존재하고 있는 `describe` 에서 만 적용된다.

// 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 Würstchen')).toBe(true);
});
test('San Juan <3 plantains', () => {
expect(isValidCityFoodPair('San Juan', 'Mofongo')).toBe(true);
});
});

Note : 최상위 스코프에 존재하는 `beforeEach`는 `describe` 안에 존재하는 `beforeEach`전에 시작 됩니다. 다음 코드를 확인해주세요.

 

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

 

Order of execution of describe and blocks

제스트는 실제 테스트를 실행하기 전에, 테스트 파일안에 존재하는 모든 `describe handler`를 실행합니다. 이 것은 셋업을 하기 위한 목적과 `describe`블럭에 존재하는 `before*`과 `after*` 핸들러를 실행 시킬 목적에 있습니다.
`describe`블락이 한번 끝나고 나면 제스트는 모든 테스트에 순차적으로 순서를 붙여 실행하고, 테스트가 완료 될 때 까지 기다렸다가 계속 진행합니다.

 

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

 

General Advice

오직 한개의 테스트만 임시적으로 실행 하고 싶은 경우, 다음과 같이 테스트의 명령어를 추가하여, 한 테스트만 실행 시킬 수 있습니다.

test.only('this will be the only test that runs', () => {
expect(true).toBe(false);
});
test('this test will not run', () => {
expect('A').toBe('A');
});

 

만약 커다란 테스트 적합을 받아야 할 때 제스트가 실패 메세지를 자주 전달 하지만 한개의 테스트만 작성하는 경우 잘 작동 하는 경우가 존재한다면, 이 것은 이 한개의 테스트 코드가 다른 테스트 코드에 영향을 미쳐서 테스트에 실패 하는 것 일 수 있습니다. 개발자는 이 테스트 실패에 대하여, `beforeEach`를 통해 테스트 코드간 공유하는 `state`를 Clearing 할 수 있습니다. 만약 공유 하는 `state`가 변경된지 확신이 서지 않는다면, `beforeEach` 함수를 통해 로그를 남겨 보는 것을 추천합니다.

#jest

반응형

'TDD > JEST' 카테고리의 다른 글

[JEST]snapshot test  (0) 2021.05.24
[JEST] Mock functions  (0) 2021.05.19
[JEST] 비동기 코드 테스트  (0) 2021.05.16
[JEST] Matcher 사용하기  (0) 2021.05.16
[JEST] 시작하기 설치 및 설정  (1) 2021.05.15
Comments