목차
- Jest란?
- tsc를 이용한 수동 테스트
- ts-jest를 이용한 테스트
- babel-jest를 이용한 테스트
- Jest 테스트 시 발생하는 이슈
1. Jest란?
Jest는 메타(페이스북)가 유지보수하는 자바스크립트 테스팅 프레임워크로 Node.js, 리액트, 앵귤러, 스벨트 등을 사용하는 프로젝트에서 사용하는 테스트 도구이다.
Jest 는 기본적으로 Node.js 환경에서 실행되는 자바스크립트 테스트 도구란 점을 인지하고 있어야 한다.
Node.js는 타입스크립트 문법을 해석할 수 없기 때문에 타입스크립트에서 Jest를 이용한 테스트를 하려면 타입스크립트 코드를 자바스크립트 코드로 변환하는 트랜스파일링(tsc 등) 과정 또는 전처리 과정(ts-jest)이 필요하다.
즉,
"타입스크립트에서 Jest를 사용하려면 전처리 도구인 ts-jest를 사용해야 하므로, 타입스크립트를 자바스크립트로 변환하는 전처리 과정이 필요하다."
Jest
- 자동화된 테스트 제공, watch 모드나 커맨드라인에서 테스트 실행 지원
- 비동기 테스트와 모킹(mocking), 스파이(spying) 등의 고급 기능을 제공하여 테스트 자동화와 유지보수를 용이하게 함
- 기본적으로 Node.js 환경을 테스트 환경으로 설정하기 때문에 Node.js의 내장 API(예: fs, path, os 등)를 사용할 수 있음
- 필요에 따라 jsdom을 이용해 브라우저 환경을 에뮬레이션 할 수 있음
타입스크립트에서 Jest를 사용한 테스트 방법
- tsc를 이용하여 자바스크립트 코드로 변환 후, Jest를 이용하여 테스트
- ts-jest를 이용하여 자바스크립트 코드로 변환 후, Jest를 이용하여 테스트
- babel-jest를 이용하여 자바스크립트 코드로 변환 후, Jest를 이용하여 테스트
세 방법의 공통점은 타입스크립트 코드를 자바스크립트 코드로 변환한 후, Jest를 이용하여 자바스크립트 코드를 테스트한다는 점이고, 변환하는 도구에 차이가 있을 뿐이다.
2. tsc를 사용하여 자바스크립트로 컴파일 후, Jest로 테스트 진행
tsc를 사용하여 타입스크립트 파일을 자바스크립트 파일로 변환한 후, Jest로 자바스크립트 테스트를 실행하는 것이 가능하다.
하지만 이 방법은 자동화된 테스트 환경을 제공하지 않으며, 타입 검사가 Jest 실행 중에 이루어지지 않는다.
그렇기 때문에 권장하는 방법은 아니다.
단점
- 타입스크립트를 수동으로 컴파일하기 때문에 자동화된 테스트 환경과는 다소 거리가 있다.
- → 테스트를 위해 매번 tsc를 실행하여 테스트를 위한 자바스크립트 파일을 준비해야 한다.
- tsc로 미리 컴파일하는 경우, Jest는 자바스크립트만 실행하므로 Jest 실행 시 타입 검사가 이루어지지 않는다.
- tsc와 Jest가 사용하는 컴파일 설정이 일치하지 않으면 문제가 발생할 수 있다.
- → tsc의 설정과 Jest가 사용하는 tsconfig.json의 설정이 다르면 테스트 환경이 일관되지 않을 수 있다.
3. ts-jest를 사용하여 타입스크립트를 테스트하는 방법
ts-jest는 타입스크립트로 작성된 프로젝트를 jest로 테스트할 수 있게 해주는 소스맵 지원 기능이 있는 Jest 변환기(Transformer)이다. 참고로 소스맵은 작성한 코드를 생성된 소스코드와 결합하기 위한 도구이다.
Jest는 Node.js 환경에서 실행되기 때문에 타입스크립트 문법을 해석할 수 없다.
타입스크립트에서 Jest를 사용한 테스트를 하기 위해선 전처리 도구인 ts-jest를 사용하여 Jest의 실행 환경에 맞는 자바스크립트 코드로 변환해야 한다.
- ts-jest는 TypeScript의 타입 검사를 지원한다. = TypeScript의 모든 기능(타입 검사 포함)을 지원한다.
- ts-jest는 TypeScript 파일을 Jest의 실행 환경에 맞는 JavaScript 코드로 변환한다.
3.1. Jest 와 ts-jest 설치
제스트 대표적인 패키지 목록
- jest
- ts-jest
- @jest/globals : describe, exoect, test 타입 체크를 할 수 있도록 함
- @types/jest : @types/jest를 사용하면 @jest/globals를 import 하지 않아도 됨
#npm
npm install --save-dev jest ts-jest @types/jest
#yarn
yarn add --dev jest ts-jest @types/jest
3.2. Jest 설정(jest.config.*)
※ jest.config.js 파일이 아닌 jest.config.ts 파일. 즉, 타입스크립트 설정파일을 이용하고 싶다면 ts-node를 추가로 설치해야 한다.
다음과 같은 에러가 발생하기 때문에 쉽게 알아챌 수 있다.
Error: Jest: 'ts-node' is required for the TypeScript configuration files. Make sure it is installed
설정에 관한 더 많은 정보( https://jestjs.io/docs/configuration)
타입스크립트(TypeScript) 설정 파일 적용(jest.config.ts)
//jest.config.ts
import type {JestConfigWithTsJest} from 'ts-jest'
const config: JestConfigWithTsJest = {
extensionsToTreatAsEsm: [],
verbose: true,
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
transfrom: {},
testPathIgnorePatterns: []
};
export default config;
자바스크립트(JavaScript) 설정 파일 적용(jest.config.js)
//jest.config.js
//commonjs 일 경우
module.exports = {
verbose: true,
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
'^.+\\.(ts)$': ['ts-jest', {useESM: true}], // TypeScript 파일을 ts-jest로 변환
'^.+\\.(tsx)$': ['ts-jest', {useESM: true}], // TypeScript JSX 파일을 ts-jest로 변환
},
moduleFileExtensions: ['js', 'ts', 'tsx', 'json', 'node'], // TypeScript 설정을 위한 옵션
};
//esnext 등 esm을 적용할 경우
const config = {
verbose: true,
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
'^.+\\.(ts)$': ['ts-jest', {useESM: true}], // TypeScript 파일을 ts-jest로 변환
'^.+\\.(tsx)$': ['ts-jest', {useESM: true}], // TypeScript JSX 파일을 ts-jest로 변환
},
moduleFileExtensions: ['js', 'ts', 'tsx', 'json', 'node'], // TypeScript 설정을 위한 옵션
};
export default config;
3.3. Jest 실행
jest를 실행하면 루트 디렉토리에 존재하는 jest.config.js 또는 jest.config.ts를 찾아서 적용시킨다.
추가 기능을 적용하고 싶다면 jest command option을 통해 적용할 수 있다.(https://jestjs.io/docs/next/cli)
#루트디렉토리를 기준으로 모든 test 파일 실행
jest
#특정 패턴이나 특정 test 파일만 선택해서 테스트 실행
jest {pattern or filename}
jest ./src/test/sample.test.js
#루트디렉토리가 아닌 특정 디렉토리에 존재하는 설정 파일을 적용해서 실행
jest --config {path}
ex)
jest --config ./conf/jest.config.ts
4. babel-jest를 이용한 테스트 방법
babel-jest는 Babel을 사용하여 JavaScript 또는 TypeScript 코드를 트랜스파일하는 도구이다. 즉, Babel을 통해 타입스크립트 코드를 자바스크립트 코드로 변환한 후 Jest를 사용해 자바스크립트 코드를 테스트할 수 있도록 해준다.
그러기 위해서 Babel을 이용해 타입스크립트를 변환하는 설정을 진행해야 하고, Jest 설정을 통해 Babel을 통해 트랜스파일링 한다는 정보를 설정해야 한다.
단점
- Babel은 타입 검사 없이 JavaScript로 변환만 수행한다.
- 즉, babel-jest는 TypeScript의 핵심 기능인 타입 검사를 하지 않으므로 타입 검사를 별도로 실행해야 한다.
- 타입 검사는 별도로 tsc나 eslint와 같은 다른 도구로 해야 한다.
- 보통 tsc --noEmit 명령을 사용하여 타입 검사를 수행한다. 이렇게 설정하면 컴파일은 하지 않지만 타입 오류는 체크할 수 있다.
빌드 속도를 고려할 때, babel-jest가 컴파일 속도가 빠르기 때문에 ts-jest보다 빠르게 실행될 수 있다.
이미 프로젝트에 Babel을 적용중이고 Babel 기반으로 프로젝트 구성을 해 놨을 경우 또는 타입 검사 없이 JavaScript만 테스트하려는 경우에 유용하다.
즉, 타입 검사를 테스트 과정에 포함시키고 싶다면 ts-jest가 더 적합하고, 빌드 속도나 설정이 간단한 것을 선호한다면 babel-jest가 더 적합할 수 있다.
4.1. Jest 와 Babel 설치
#npm
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-typescript
npm install --save-dev jest @types/jest babel-jest
#yarn
yarn add --dev @babel/core @babel/cli @babel/preset-env @babel/preset-typescript
yarn add --dev jest @types/jest babel-jest
4.2. Jest와 Babel 설정
먼저 Babel을 이용해 타입스크립트를 트랜스파일링 할 수 있도록 설정해야 한다.(이미 babel을 사용 중이라면 생략 가능)
Jest에서 babel-jest를 사용하려면 jest.config.js에서 transform 옵션을 설정하여 Babel을 사용하도록 해야 한다.
자바스크립트 설정 파일로 Babel 설정
//babel.config.js
//commonjs 일 경우
module.exports = {
presets: [
'@babel/preset-env',// 최신 JavaScript 문법을 구버전 브라우저/Node.js 환경에 맞게 변환
'@babel/preset-typescript',// TypeScript 코드 변환을 위한 preset
],
};
//es2022 or esnext (esm을 적용할 경우)
const config = {
presets: [
'@babel/preset-env',// 최신 JavaScript 문법을 구버전 브라우저/Node.js 환경에 맞게 변환
'@babel/preset-typescript',// TypeScript 코드 변환을 위한 preset
],
};
export default config;
자바스크립트 설정 파일로 Jest 설정
설정에 관한 더 많은 정보( https://jestjs.io/docs/configuration)
//jest.config.js
//commonjs 일 경우
module.exports = {
transform: {
'^.+\\.(ts)$': 'babel-jest', // TypeScript 파일을 babel-jest로 변환
'^.+\\.(tsx)$': 'babel-jest', // TypeScript JSX 파일을 babel-jest로 변환
},
moduleFileExtensions: ['js', 'ts', 'tsx', 'json', 'node'], // TypeScript 설정을 위한 옵션
};
//esnext 등 esm을 적용할 경우
const config = {
transform: {
'^.+\\.(ts)$': 'babel-jest', // TypeScript 파일을 babel-jest로 변환
'^.+\\.(tsx)$': 'babel-jest', // TypeScript JSX 파일을 babel-jest로 변환
},
moduleFileExtensions: ['js', 'ts', 'tsx', 'json', 'node'], // TypeScript 설정을 위한 옵션
};
export default config;
4.3. Jest 테스트 실행
#루트디렉토리를 기준으로 모든 test 파일 실행
jest
#특정 패턴이나 특정 test 파일만 선택해서 테스트 실행
jest {pattern or filename}
jest ./src/test/sample.test.js
#루트디렉토리가 아닌 특정 디렉토리에 존재하는 설정 파일을 적용해서 실행
jest --config {path}
ex)
jest --config ./conf/jest.config.ts
5. Jest 테스트 시 발생하는 이슈
타입스크립트에서 Jest 테스트 과정에서 주로 발생하는 이슈로 module import 이슈가 발생하는 경우가 많다.
Jest encountered an unexpected token
module을 import 할 수 없는 문제 발생
이 문제는 대부분 commonjs, esnext(esm). 즉, 자바스크립트의 모듈 관련 문제인 경우가 많다.
타입스크립트에서 Jest 테스트는 Jest 테스트 환경을 구성할 때 Jest가 tsconfig.json을 가져다 타입스크립트 실행환경을 구성하게 된다.
그렇기에 모듈 시스템 역시 tsconfig.json에 의존하게 되는데 이 때 jest와 typescript 간의 실행환경의 일관되지 않을 경우 해당 발생하는 경우가 많다.
jest는 기본적으로 루트디렉토리에 위치하는 tsconfig.json을 읽어 들이기 때문에 jest.config.js에서 설정하는 rootDir 과 tsconfig.json에서 설정하는 rootDir을 잘 연동하여 해당 문제를 해결할 수 있다.
이 과정이 번거롭다면 tsconfig.json과 jest.config.js을 모두 루트디렉토리에서 설정 및 사용하도록 하자...
Reference.
https://jestjs.io/docs/configuration
'nodejs' 카테고리의 다른 글
[DevOps] ESLint, Webpack, Babel 설명, 설치 방법 포함 (0) | 2024.12.20 |
---|