[ 살펴보기 ] Jest - Global APIs
![[ 살펴보기 ] Jest - Global APIs](https://cdn.hashnode.com/res/hashnode/image/upload/v1730098277424/4975c019-4702-407f-978c-515fb140ee27.jpeg)
아래 포스트의 Jest 테스트 환경은 Vite를 통해 구성된 React project에서 진행되며 다른 환경에서의 테스트 구성은 Jest Documentation에서 확인할 수 있습니다. ( Reference - Testing Web Frameworks )
Jest package를 설치하고 ( npm install -D jest ) npm init jest@latest명령어를 실행하면 초기 설정을 위한 prompt가 나오며 prompt에 대한 답변에 따라 jest.config.js configuration 파일을 생성해 준다.
만약 jest test 환경을 jsdom으로 설정했다면 다음 package를 추가로 설치해야 한다.
npm install -D jest-environment-jsdom
테스트를 진행하기 위한 필자의 jest.config.js는 다음과 같다.
/** @type {import('jest').Config} */
const config = {
testEnvironment: "jsdom",
};
export default config;
이제 package.json 파일에 test를 실행하기 위한 script가 추가되었는지 확인하고 추가되어 있지 않다면 다음과 같이 추가 해준다.
...
"scripts": {
...
"test": "jest"
}
...
이제 다음과 같이 간단한 test파일을 생성해 test code를 추가해보자.
// main.test.js
test('adds 1 + 2 to equal 3', () => {
expect(1+3).toBe(3);
});
위의 코드를 추가하고 npm run test를 실행하면 jest를 통해 작성한 test가 실행되는 것을 확인할 수 있다. test와 expect는 jest에서 제공하는 global api이므로 따로 import하지 않아도 jest를 실행하면 jest가 자동으로 global environment에 추가 해준다.
Typescript를 사용한다면 추가적인 설정이 필요하다. Jest가 typescirpt file을 compile할 수 있도록 다음 package를 설치하고 configuration에 추가해준다.
npm install -D ts-jest @types/jest
jest.config.js
/** @type {import('jest').Config} */
const config = {
testEnvironment: "jsdom",
transform: {
"^.+.tsx?$": ["ts-jest", {}],
},
};
export default config;
추가로 test file이 typescript라면 jest global apis를 사용할 때 type 오류가 발생할 것이다. type 오류를 해결하기 위해선 다음과 같이 @jest/globals를 추가로 설치에서 global api를 직접 import해서 사용할 수 있다.
npm install -D @jest/globals
// main.test.ts
import { expect, test } from "@jest/globals";
test("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
또는 @types/jest package를 설치하고 기존과 같이 별도의 import 없이 사용할 수 있다.
npm install --D @types/jest
// main.test.ts
test("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
이제 Jest에서 제공하는 Globals api 중 일부를 살펴보자. 모든 api list는 다음 documentation에서 확인할 수 있다 ( Reference - Jest - Globals )
test
Test를 실행할 code의 이름과 내용을 선언한다. 예를 들어 다음은 expect function에 전달되는 함수의 결과를 테스트하는 간단한 test code다.
test("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
expect
실제로 테스트할 연산을 전달하고 연산의 결과를 검사하는 matcher를 추가해 최종 결과를 검사할 수 있다. 아래의 예제에선 expect에 전달한 function의 연산 결과가 7일 때 정상이므로 toBe matcher를 통해 해당 사항을 설정해주고 있다.
const sum = (firstNum: number, secondNum: number) => firstNum + secondNum;
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
test.each
하나의 Test block에서 Test 값을 여러가지 설정하여 결과를 테스트할 때 사용할 수 있다.
test.each([
{ a: 1, b: 1, expected: 2 },
{ a: 1, b: 2, expected: 3 },
{ a: 2, b: 3, expected: 5 },
])("test sum function - current : ($a, $b)", ({ a, b, expected }) => {
expect(sum(a, b)).toBe(expected);
});
Test.each api interace는 다음과 같다.
test.each(table)(name, fn, timeout)
table parameter에 테스트할 값과 예상 결과값을 전달하고 name 부분은 test의 name을 설정한다. 위의 예제와 같이 전달하는 variable을 $variable_name 형식으로 사용할 수 있다. 그리고 fn에는 실행될 test code를 선언하고 timeout은 optinal 값으로서 각각의 test가 실행될 수 있는 최대 시간을 설정할 수 있다. default는 5 seconds로 설정되어 있다.
위의 테스트를 실행하면 결과는 아래와 같다.
PASS __test__/main.test.ts
√ test sum function - current : (1, 1)
√ test sum function - current : (1, 2)
√ test sum function - current : (2, 3)
test.only, test.skip
test.only 또는 test.skip을 통해 test code 중 특정 test가 실행하거나 특정 test를 skip할 수 있다. 다음과 같이 test 파일에 test.only를 사용하는 test code가 있으면 해당 파일에선 test.only가 적용된 test를 제외하고 모든 test가 skip 된다.
// skip 된다.
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
// test가 실행된다.
test.only("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
반면 skip을 통해 특정 test code만 test실행 시 제외할 수 있다.
// test가 실행된다.
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
// skip 된다.
test.skip("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
describe
관련된 여러 test를 group화 할 때 사용할 수 있다. 예를 들어 두 수를 빼는 substract function을 위한 test를 모아서 group화 한다고 가정해보자.
const subtract = (firstNum: number, secondNum: number) => firstNum - secondNum;
describe("test subtract behavior", () => {
test("test subtrack", () => {
expect(subtract(5, 2)).toBe(3);
});
test("test subtrack - should not to be lower than 0", () => {
expect(subtract(2, 5)).toBeGreaterThanOrEqual(0);
});
});
위의 예제에서 두 번째 테스트에서 결과 값이 0이거나 0보다 큰 수이길 기대하지만 결과는 -3이 나오므로 위의 테스트는 실패한다.
describe.each
Describe역시 test.each와 같이 하나의 describe block에서 여러 테스트 값을 테스트 하고 싶을 때 describe.each를 사용할 수 있다. 만약 두 숫자를 뺀 값을 반환하는 함수를 테스트 하고 두 숫자를 뺀 값이 0보다 작을 때는 0을 반환하게끔 function이 구성되어 있다고 가정해보자.
describe each를 통해 다음과 같이 각 테스트 값과 결과 값에 따라 각자 테스트를 진행할 수 있다.
describe.each([
{ a: 5, b: 2, expected: 3 },
{ a: 2, b: 5, expected: 0 },
])("test subtract behavior : current - ($a, $b)", ({ a, b, expected }) => {
test("test subtrack", () => {
expect(subtract(a, b)).toBe(expected);
});
test("test subtrack - should not to be lower than 0", () => {
expect(subtract(a, b)).toBeGreaterThanOrEqual(expected);
});
});
위의 코드를 실행하면 결과는 다음과 같다.
PASS __test__/main.test.ts
test subtract behavior : current - (5, 2)
√ test subtrack
√ test subtrack - should not to be lower than 0 (1 ms)
test subtract behavior : current - (2, 5)
√ test subtrack
√ test subtrack - should not to be lower than 0
Test Suites: 1 passed, 1 total
Tests: 4 passed, 4 total
afterAll
Afterall에 function을 전달하면 현재 test file의 test 실행이 모두 종료되고 나서 전달한 function이 실행된다. function은 test 성공, 실패여부와 무관하게 실행된다.
afterAll(() => {
console.log(" all test completed ");
});
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
test("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
afterEach
현재 test file의 각각의 test의 실행이 종료되고 나서 실행된다. 즉, 아래의 경우에는 test가 두 개 이므로 AfterEach로 전달한 function이 두 번 실행된다. test의 성공, 실패 여부와 무관하게 실행된다.
afterEach(() => {
console.log(" after each test ");
});
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
test("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
beforeAll
현재 test file의 test code가 실행되기 전에 실행되는 function을 전달할 수 있다.
beforeAll(() => {
console.log(" before all test ");
});
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
test("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
beforeEach
현재 test file에 선언된 각 test code가 실행되기 전에 실행되는 function을 전달할 수 있다.
beforeEach(() => {
console.log(" before each test ");
});
test("test sum function", () => {
expect(sum(2, 5)).toBe(7);
});
test("test substract function", () => {
expect(subtract(5, 2)).toBe(3);
});
![[ 살펴보기 ] RDB - Relationships](https://cdn.hashnode.com/res/hashnode/image/upload/v1739711556668/48dc9e84-a621-42aa-9c9f-5fc5c436f0ec.jpeg)
![[ 살펴보기 ] MySQL - Data types](https://cdn.hashnode.com/res/hashnode/image/upload/v1739593589113/530f8704-4d27-42c9-a451-bb5c63150b99.jpeg)
![[ 살펴보기 ] TypeORM - Transactions, Migration](https://cdn.hashnode.com/res/hashnode/image/upload/v1739106042581/980b8133-61d4-406a-a026-65be9c28eace.jpeg)
![[ 살펴보기 ] TypeORM - Relations](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666874402/b688bd0b-b6bb-4f43-87d8-c1b46b59f1b7.jpeg)
![[ 살펴보기 ] TypeORM - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666803591/bef5df17-7dc7-4123-ae55-004d5042df39.jpeg)