오늘은 자바스크립트의 또 다른 테스트 프레임 워크인 Jest
를 소개해보려고 합니다. 예전에 Jasmine을 소개해드렸었는데요. 사용법이 거의 비슷합니다. 그 이유는 Meta에서 Jasmine
을 기반으로 Jest
프레임 워크를 만들었기 때문입니다.
테스트 프레임워크 점유율을 비교해보면 Jest
가 가장 압도적인 다운로드 수를 기록하고 있음을 알 수 있습니다.그렇다면 왜 Jest
의 점유율이 이토록 높을까요?
그 이유는 간단하게 사용할 수 있다라는 점 입니다. Mocha
라는 프레임워크도 상당히 강력하고 확장성이 넒지만, 확장성이 넒다는 말에 항상 따라오는 세팅이 번거롭다.라는 단점이 있습니다. Jasmine
은 Jest를 기반으로 만들었기에 좀 더 많은 편의성을 위해 Jasmine 대신 Jest를 사용하게 되는 것이죠. 그리고 React.js
를 만든 메타 그룹에서 만들었기에 React.js 환경에서 원활한 테스트를 할 수 있기에 리액트 사용자가 많은만큼 Jest
가 있기있을 수 밖에 없는 것 입니다.
Jest
는 npm
또는 yarn
을 통해서 설치할 수 있습니다.
npm install --save-dev jest
yarn add --defv jest
설치 후 package.json
파일을 생성 또는 파일에 아래 내용을 추가해주세요.
"scripts": {
"test": "jest"
}
jasmine
을 알고 계시다면 그 문법을 거의 그대로, 또는 모르더라도 직관적이고 간단하게 테스트 구문을 생성할 수 있습니다.
test()
로 테스트 구문을 생성합니다. 다음의 양식을 따른다고 생각하시면 됩니다.
test('테스트 케이스 설명', () => {
expect(테스트 대상).Matcher
})
그럼 실제로 간단한 코드를 테스트 해보겠습니다.
test('1 더하기 2는 3?', () => {
expect(1 + 2).toEqual(3);
});
expect()
에 인수로 테스트 할 대상을 넣고 그 뒤에 toEqaul()
이라는 Matcher
를 넣었습니다. Matcher
는 테스트 결괏값과 비교해 테스트 결과를 반환하는 함수입니다.
테스트 실행은 터미널에서 npm start
또는 yarn test
를 입력하여 사용합니다. 만약 성공하면 아래와 같이 PASS했다는 안내 문구가 터미널에 나타나게 됩니다.실패하는 코드를 작성했을 경우, 실패했다고 뜨며 문제가 발생한 부분이 어디인지도 알려줍니다.
Node.js
의 모듈 문법을 통해 특정 함수를 모듈식으로 불러와서 테스트할 수도 있습니다.
테스트를 실행하기 전과 후에 처리할 내용을 따로 기술할 수도 있습니다.
beforeEach()
는 각 테스트 함수가 실행되기 전, afterEach()
는 각 함수가 실행 된 후 처리를 담당하는 함수입니다. 테스트에서 어떤 변수, 객체 등을 사용 할 때 beforeEach()
를 이용해서 초기화 과정을 할 수 있습니다.
beforeEach(() => {
선처리 코드
});
afterEach(() => {
후처리 코드
});
test("test", () => {
테스트
});
이전에 본 beforeEach(), afterEach()
가 각 테스트 케이스 직전/후로 실행되는 선후처리였다면 beforeAll()
, afterAll()
은 해당 테스트 코드의 맨 처음과 마지막에 딱 한 번만 수행되는 처리입니다.
beforeAll(() => {
선처리 코드
});
afterAll(() => {
후처리 코드
});
test("test", () => {
테스트
});
테스트의 상황에 따라서 알맞은 전후처리 메소드를 사용하는 것이 좋습니다.
Matcher
는 값을 테스트하는 함수입니다. 테스트 케이스가 무궁무진한 만큼 다양한 Matcher들이 존재하는데 몇 가지만 소개하도록 하겠습니다.
toBe()
는 가장 간단한 비교 함수입니다. 인수로 전달한 값이 expect()
에서 나온 결괏값과 일치하면 PASS를 합니다. toBe()
는 비교를 할 때 타입을 기본형(number, string, boolean, symbol)만을 가지고 비교합니다.
toEqual()
은 toBe()
와 마찬가지로 expect()
의 결괏값과 비교하여 일치하면 PASS하는 함수입니다. toBe()
와의 차이점은 객체로 비교를 한다는 점입니다. (비유하자면 ==와 ===의 차이) 실제로 대부분의 테스트값은 객체를 비교하는 경우가 많으므로 기본적으로 toBe()
보다는 toEqual()
을 사용하는 것을 권장하고 있습니다.
toStrictEqual()
은 이름에서도 느껴지는 더 엄격한 검사는 수행하는 비교입니다. toStrictEqual()
은 특정 요소에 undefined
값이 오는 것을 허가하지 않습니다. toEqual()
에서는 undefined
를 통과시키기 때문에 자칫하면 놓칠 수 있는 오류를 잡아줍니다. 공식 문서에도 toStrictEqual()
의 사용을 권장하고 있습니다.
toBeTruthy()
, toBeFalsy()
는 expect()의 결과가 각각 참으로 간주되는 값과 거짓으로 간주되는 값인지를 확인합니다. 참으로 간주되는 Truthy한 값과 거짓으로 간주되는 Falsy한 값은 다음과 같습니다.
toBeNull()
은 expect의 값이 null
일때 PASS입니다.
toBeUndefined()
는 undefined
일때, toBeDefined()
는 그 반대로 expect의 값이 defined
인 경우에 PASS를 합니다.
toMatch()
는 문자열 검사에 사용되는 Matcher입니다. 단순한 문자열의 경우 toEqual()
을 통해 검사할 수 있으나, 정규식
을 기반으로한 문자열을 검사할 때에는 toMatch()
를 사용해서 검사하게 됩니다.
toContain()
은 배열이나 반복가능한 객체에서 특정 요소가 포함되어있는지 확일할 때 사용하는 Matcher입니다.
추가적으로 요소가 아닌 배열의 길이를 검사하고 싶은 경우 toHaveLength()
를 사용합니다.
특정 상황에서 오류를 발생시키는지 확인하고자 할 때 toThrow()
를 이용합니다. 이 Matcher는 인자를 받기도 하는데, 인자를 주게되면 문자열 인자의 경우 에러 메세지 검증, 정규식 인자는 정규식을 검사하는 역할도 합니다.
특정 함수가 호출되었는지 확인하고자 할 때, toHaveBeenCalled()
를 사용합니다.
추가적으로 toHaveBeenCalled()
는 기반 프레임워크인 jasmine
으로부터 상속되었기 때문에 이런 길고 어려운 이름을 갖게되었습니다. 그래서 따로 별칭(alias)인 toBeCalled()
를 가지고 있습니다. 이 두 가지 Matcher의 동작은 완전히 동일하다고 하므로 쓰기 더 편한 toBeCalled()
를 사용해도 됩니다.