jest의 사전 설정과 예제를 알아보자.
코딩앙마의 jest강의 유튜브를 기초로 정리한 내용이다.
링크 : https://www.youtube.com/watch?v=g4MdUjxA-S4&list=PLZKTXPmaJk8L1xCg_1cRjL5huINlP2JKt
Jest는 페이스북에서 만든 JavaScript testing framework이다.
Zero Config를 지향하며, 따로 설정하지 않아도 빠르게 테스팅 환경을 만들 수 있다는 것이 큰 장점이다.
jest를 설치하기 위해 node.js 패키치와 jest를 설치한다.
npm init
npm install jest --save-dev
scripts의 test를 jest로 바꿔준다.
{
...
"scripts": {
"test": "jest"
},
}
테스트를 위해 테스트할 함수파일(fn.js
)와 테스트코드를 작성할 파일(fn.test.js
)를 생성한다.
파일명은 __test__
또는 test.js
로 끝나면 자동으로 인식하므로 선택하면 된다.
테스트 할 함수를 작성한다.
fn.js 파일에 작성
const fn = { add : (n1, n2) => n1 + n2, };
module.exports = fn;
테스트 코드의 구성은 다음과 같은데, test()
의 함수 속에서 일어나는 것을 테스트 케이스라고 한다.
여러개의 test()
를 구성할 수 있다.
expect()
에는 기존 값을 넣고, toBe()
에는 결과 값을 넣는다. 기존 값이 결과 값으로 나오면 ‘성공’ 다른 값이 나오면 ‘실패’하게 된다.
const 테스트함수 = () => { // 테스트에 사용할 콜백함수
expect(기존값).toBe(미래값) ;
}
test("테스트시 출력할 문자열", 테스트함수)
fn.test.js
성공할 함수 2개와 실패할 함수 1개를 쓰면 아래처럼 된다.
const fn = require("./fn"); // 검증할 함수를 불러온다.
test("1은 1이야", () => {
expect(1).toBe(1); // 검증할 값 -> 결과
});
test("2더하기 3은 5야", () => { // 성공할 테스트 케이스
expect(fn.add(2, 3)).toBe(5);
});
test("3더하기 3은 5야", () => { // 실패할 테스트 케이스
expect(fn.add(3, 3)).toBe(5);
});
디렉토리 전체 테스트
디렉토리를 순회하면서 test파일을 전부 실행시킨다.
npm test
한가지 파일만 실행하려면 아래처럼 작성하면 된다.
npm test 파일명
아래처럼 test 성공은 체크 표시로, 실패는 x표시가 뜨며, 실패한 위치를 보여준다.
npm test
jest@1.0.0 test
jest
FAIL ./fn.test.js
√ 1은 1이야 (2 ms)
√ 2더하기 3은 5야
× 3더하기 3은 5야 (2 ms)
● 3더하기 3은 5야
expect(received).toBe(expected) // Object.is equality
Expected: 5
Received: 6
10 |
11 | test("3더하기 3은 5야", () => {
 >12 | expect(fn.add(3, 3)).toBe(5);
 | ^
 13 | });
 14 |
 15 |
at Object.toBe (fn.test.js:12:24)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 0 total
Time: 0.802 s
Ran all test suites.
toBe부분 앞에서 not을 표현하기 위해 쓴다.
test("3더하기 3은 5가 아니야", () => {
expect(fn.add(3, 3)).not.toBe(5);
});
객체의 값을 비교할 때 사용한다.
toBe
를 쓰게되면 객체의 주소값으로 판단하여 실패하게 된다.
fn.test.js
const fn = require("./fn");
test("이름과 나이로 객체를 생성", () => {
expect({ name: "heisje", age: 30, }).toBe({ name: "heisje", age: 30, });
});
test("이름과 나이로 객체를 생성", () => {
expect({ name: "heisje", age: 30, }).toEqual({ name: "heisje", age: 30, });
});
테스트 결과
If it should pass with deep equality, replace "toBe" with "toStrictEqual"
라는 문구와 함께 실패하게 된다.
FAIL ./fn.test.js
✕ 이름과 나이로 객체를 생성 (3 ms)
✓ 이름과 나이로 객체를 생성
● 이름과 나이로 객체를 생성
expect(received).toBe(expected) // Object.is equality
If it should pass with deep equality, replace "toBe" with "toStrictEqual"
Expected: {"age": 30, "name": "heisje"}
Received: serializes to the same string
2 |
3 | test("이름과 나이로 객체를 생성", () => {
> 4 | expect({ name: "heisje", age: 30, }).toBe({ name: "heisje", age: 30, });
| ^
5 | });
6 |
7 | test("이름과 나이로 객체를 생성", () => {
at Object.toBe (fn.test.js:4:39)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 passed, 2 total
Snapshots: 0 total
Time: 0.198 s, estimated 1 s
Ran all test suites.
undefined인 항목까지도 체크 가능하다.
// toStrictEqual 실패
test("이름과 나이로 객체를 생성", () => {
expect({ name: "heisje", age: 30, gender: undefined}).toStrictEqual({ name: "heisje", age: 30, });
});
// toEqual 성공
test("이름과 나이로 객체를 생성", () => {
expect({ name: "heisje", age: 30, gender: undefined}).toEqual({ name: "heisje", age: 30, });
});
이름에서 직역가능한 것은 따로 적지 않았다.
toBe
toBeCloseTo
toEqual
toBeNull
toBeUndefined
toBeDefined
toBeTruthy
toBeFalsy
toBeGreaterThan
toBeGreaterThanOrEqual
toBeLessThan
toBeLessThanOrEqual
toMatch
에 정규 표현식을 넣으면 되고, 정규표현 식 뒤 i
를 통해 대소문자 구분을 없애줄 수 있다.
test("Heisje에 e라는 글자가 있나?", () => {
expect("Heisje").toMatch(/e/);
});
test("Heisje에 h라는 글자가 대소문자 구분하지 않고 있나?", () => {
expect("Heisje").toMatch(/h/i);
});
배열 요소인지 판단
test("유저 리스트에 Heeje가 있나?", () => {
const user = 'Heeje'
const userList = ["Tom", "Mike", "Heeje"]
expect(userList).toContain(user);
});
에러반환이 성공적으로 됐는지 판단한다.
toThrow
에 인자가 없으면 에러 반환만 확인하고, 인자가 있으면 에러의 값이 같은지도 비교한다.
const fn = {
throwErr: ()=>{
throw new Error('xx')
}
};
test("에러 반환 테스트", () => { // 성공
expect(()=>fn.throwErr()).toThrow();
});
test("에러 반환 테스트", () => { // 실패
expect(()=>fn.throwErr()).toThrow('oo');
});