Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this.
종종 테스트를 작성할때 테스트가 실행되기전 설정 작업이 필요하면, 테스트가 실행되고 나서 설정 작업이 필요하다. Jest는 이런 것을을 조작하게 돕니다.
Repeating Setup For Many Tests
If you have some work you need to do repeatedly for many tests, you can use beforeEach
and afterEach
.
만약 여러 테스트에 반복되는 작업이 필요하며, 너는 beforeEach
and afterEach
을 사용할 수 있다.
For example, let's say that several tests interact with a database of cities. You have a method initializeCityDatabase()
that must be called before each of these tests, and a method clearCityDatabase()
that must be called after each of these tests. You can do this with:
예를들어, 각각의 테스트에서 데이터베이스로 통신한다고 해보자. 각각의 테스트 전에 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
and afterEach
can handle asynchronous code in the same ways that tests can handle asynchronous code - they can either take a done
parameter or return a promise. For example, if initializeCityDatabase()
returned a promise that resolved when the database was initialized, we would want to return that promise:
beforeEach
and afterEach
는 tests can handle asynchronous code 것과 같은 방법으로 비동기 코드를 컨트롤 할 수 있다 - 그것은 done
파라미터 취하거나 promise 를 리턴할 수 있다. 예를들어 initializeCityDatabase()
는 데이터베이스가 초기화될 때 resolved된 promise를 리턴한다면, 그 promise는 우리가 원한 것이다.(??)
beforeEach(() => {
return initializeCityDatabase();
});
One-Time Setup
In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't just do it inline. Jest provides beforeAll
and afterAll
to handle this situation.
어떤 경우는, 파일이 시작될 때 오직 한번만 설정이 될 필요가 있다. 특히 설정이 인라인으로 할 수 없는 비동기작업일 때 문제가 될 수 있다. Jest는 이런 상황을 조작하기 위해 beforeAll
and afterAll
를 제공한다.
For example, if both initializeCityDatabase
and clearCityDatabase
returned promises, and the city database could be reused between tests, we could change our test code to:
예를들어 initializeCityDatabase
and clearCityDatabase
가 promises를 리턴하고, 그 도시 테이터베이스는 테스트간에 재사용될 수 있다면, 코드를 다음과 같이 변경 할 수 있다.
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
By default, the before
and after
blocks apply to every test in a file. You can also group tests together using a describe
block. When they are inside a describe
block, the before
and after
blocks only apply to the tests within that describe
block.
기본적으로, before
and after
블록은 파일안에서 모든 테스트에 적용된다. 또한 describe
블록을 사용하여 그룹 테도 함께 할 수 있다. describe
블록 안에서는, before
and after
블록이 그 안의 테스트들에만 적용된다.
For example, let's say we had not just a city database, but also a food database. We could do different setup for different tests:
예를들어, 우리가 도시 데이터베이스 말고 음식 데이터베이스도 갖는다고 하자. 다른 테스트를 위해 다른 설정을 할 수 있다:
// 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.
최상위 레벨의 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 test blocks
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 in before*
and after*
handlers rather in 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.
Jest는 실제 테스트를 실행하기 전에 테스트 파일에서 모든 describe 핸들러들를 실행한다. 이것은 describe 블록에서 보다 before*
and after*
핸들러에서 setup 과 teardown 하는 또다른 이유이다(??). describe 블록이 완료되면, 기본적으로 Jest는 모든 테스트를 수집 단계에서 발생한 순서데로 순차적으로 실행하고, 각 테스트가 완료되길 기다렸다가 이동하기 전에 정리 합니다.
Consider the following illustrative test file and output:
다음과 같은 테스트 파일과 출력을 고려해 보자:
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
General Advice
If a test is failing, one of the first things to check should be whether the test is failing when it's the only test that runs. In Jest it's simple to run only one test - just temporarily change that test
command to a test.only
:
만약 테스트가 실패하면, 체크해야할 첫번째가 실행하되는 오직 하나의 테스트가 될 때 실패된건지 여부를 확인해 봐야 한다ㅋ. 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');
});
If you have a test that often fails when it's run as part of a larger suite, but doesn't fail when you run it alone, it's a good bet that something from a different test is interfering with this one. You can often fix this by clearing some shared state with beforeEach
. If you're not sure whether some shared state is being modified, you can also try a beforeEach
that just logs data.
만약 대규모의 suite의 일부로 실행될 때 종종 실패하는 테스트가 있는데, 단독으로 실행시에는 실패하지 않는다면, 이것은 무엇인가 다른 테스트에서 방하하고 있다는 좋은 확신이다. beforeEach
를 사용하여 어떤 공유 상태를 지워 서 문제를 해결 할 수 있다. 만약 어떤 공유 상태가 수정되었는지 여부가 확실하지 않으면, 데이터 로깅하는 beforeEach
를 시도해 볼 수 있다.