본문으로 바로가기

https://jestjs.io/

 

Jest

By ensuring your tests have unique global state, Jest can reliably run tests in parallel. To make things quick, Jest runs previously failed tests first and re-organizes runs based on how long test files take.

jestjs.io

 

installation 

(1) 설치

yarn add jest jest-cli -D
yarn add  @types/jest ts-jest -D // typescript 환경

 

정말 단순하게는, [file].test.js 꼴의 폴더를 만들고 이를 jest 명령어만을 사용해서 테스트를 진행할 수도 있다.

jest는 default로, [file].(test|spec).js 꼴의 파일, __test__ 폴더 내에 있는 파일들은 모두 테스트 파일로 인식한다.

해당하는 모든 테스트 코드가 아니라 특정 테스트 코드만 실행하고 싶다면 jest [테스트 코드 경로] 꼴로 사용하면 된다.

 

"scripts": {
  "test": "jest",
  "test-sum-func": "jest ./sum.test.js",
},
📁 sum.js
function sum(a, b) {
  return a + b;
}

📁 sum.test.js
import sum from './sum';

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

 

 

(2) jest-cli option

 

https://jestjs.io/docs/cli

 

단순히 jest 명령 뿐만 아니라 여러 option을 통해 테스트를 구동할 수 있다. 아래는 Nest 프로젝트를 생성하면 자동으로 세팅해주는 test 관련 명령어들이다. 이렇게, 필요할 때 찾아서 직접 구성하면 된다. 여기서는 우선 넘어가자.

"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"

 

넘어가기 전에, 아주 자주 사용하는 coverage만 훑어보고 갑시다.

 

- coverage

jest --coverage

coverage는 관련 보고서도 자동으로 만들어준다. 최상위 폴더에 ./coverage를 확인해보자.

textRegex, textMatch에 해당하지 않는 파일을 coverage로 포함하지 않는데, 

jest 구성에서 collectCoverageFrom를 통해 coverage 대상을 명시할 수 있습니다.

저는 최상위 경로에 있는 *js, *ts를 모두 포함시켰습니다.

"collectCoverageFrom": [
  "./*.[jt]s"
]

 

그 외에 coverageThreshold를 통해 최소 요구 coverage 정도를 설정할 수 있는 등의 기능이 있습니다.

 

jest configuring

 

jestjs.io/docs/en/configuration

 

Configuring Jest · Jest

Jest's configuration can be defined in the package.json file of your project, or through a jest.config.js, or jest.config.ts file or through the --config option. If you'd like to use your package.json to store Jest's config, the "jest" key should be used o

jestjs.io

 

jest 명령어를 통해 jest.config.js를 생성합니다. 옵션을 적절히 선택해서 jest.config.js를 잘 설정하도록 합시다.

jest --init // jest.config.js 생성

✔ Would you like to use Typescript for the configuration file?
✔ Choose the test environment that will be used for testing 
✔ Do you want Jest to add coverage reports? 
✔ Which provider should be used to instrument code for coverage? 
✔ Automatically clear mock calls and instances between every test?  

 

한편, jest.config.js를 생성하지 않고도 package.json 내에서도 jest 관련 설정을 할 수도 있습니다. 

Nest에서 그렇게 구성되어 있는데, package.json을 확인해보면 jest 세팅이 다음과 같이 되어 있습니다.

다만, 저는 개인적인 취향으론 package.json에 몰아 넣기보다는 prettierrc, babelrc도 따로 만드는 타입이라, 별도의 파일로 분리하는 것이 좋아 보입니다. 

 

"jest": {
  "moduleFileExtensions": [
    "js",
    "json",
    "ts"
  ],
  "rootDir": "src",
  "testRegex": ".*\\.spec\\.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  },
  "collectCoverageFrom": [
    "**/*.(t|j)s"
  ],
  "coverageDirectory": "../coverage",
  "testEnvironment": "node"
}

 

jest 옵션에는 많은 옵션들이 존재하지만, 기본적으로 사용된 옵션을 위주로 알아봅시다~

 

 

(1) jest.config.js 구성요소

 

https://jestjs.io/docs/configuration 에 기반하여 작성되었습니다.

 

 

moduleFileExtensions 

jestjs.io/docs/en/configuration#modulefileextensions-arraystring

Default: ["js", "json", "jsx", "ts", "tsx", "node"]

 

여러분들이 작성한 모듈의 확장자를 배열로 적어주면 된다. 가장 자주 사용되는 확장자부터 차례대로 적어주면 된다. 만약 TS를 주로 사용하는 프로젝트라면 ts, tsx를 먼저 위치시켜주면 된다.

Nest에서는 allowJS를 켜고 사용하는 사람의 편의성 때문인지 js, json, ts 순으로 배치했다.

일반적인 프로젝트에서는 굳이 건드릴 필요는 없다.

 

 

rootDir

jestjs.io/docs/en/configuration#rootdir-string

Default: Jest config file이 있는 경로 혹은 package.json이 있는 경로. 둘 다 존재하지 않는다면 현재 경로를 rootDir로 설정함.

 

프로젝트 구조에 따라 종종 src나 lib와 같은 다른 경로를 rootDir로 지정하고 싶다면 적어주면 된다. 여튼 진입점을 적어주면 된다. Nest에서는 비즈니스 로직이 존재하는 코드가 전부 ./src이다.

 

 

testRegex, testMatch

 

The pattern or patterns Jest uses to detect test files.

둘중 하나만 사용하라고 하네요.

기본값으론 __tests__ 폴더 내에 있는 모든 것, *.(spec|test).(js|ts) 형식인 모든 파일을 test 대상으로 여깁니다. 굳이 또 설정할 필요는 없없을듯?

(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$ // testRegex
[ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ] // testMatch

 

공식 문서에 나와있는 예시는 다음과 같다.

├── __tests__
│   └── component.spec.js # test
│   └── anything # test
├── package.json # not test
├── foo.test.js # test
├── bar.spec.jsx # test
└── component.js # not test

 

 

transform

jestjs.io/docs/en/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object

Default: {"\\.[jt]sx?$": "babel-jest"}

 

쉽게 말해 test는 일반 로직과 분리되어 동작합니다. 때문에 babel이나 webpack으로 변환되는 과정을 따로 작성해주어야 하는데 참으로 고생스러운 일입니다. transoform은 이런 변환을 자동으로 해줍니다.

 

기본값의 정규식을 해석해보자면 \.js, \.jsx, \.ts, \.tsx인 경우 babel-jest로 변환하라는 것입니다. 물론 babel-jest 플러그인을 설치해줘야 합니다. github.com/facebook/jest/tree/master/packages/babel-jest#setup 여기서 확인해보실 수 있습니다.

 

Nest에서는 "transform": {"^.+\\.(t|j)s$""ts-jest"} 로 지정되어 있습니다. 즉, ..\.js ..\.ts (depth는 상관 없음. .+는 .이 1개 이상 존재함을 의미) 꼴인 파일을 모두 ts-jest로 transform하는 것을 의미합니다. ts-jest는 github.com/kulshekhar/ts-jest 여기를 참고합시다.

 

 

collectCoverageFrom

jestjs.io/docs/en/configuration#collectcoveragefrom-array

Default: undefined

 

glob patterns으로 coverage 정보를 위해 수집되어야 할 파일들을 명시합니다. glob pattern에 해당하는 파일에 대한 test가 없다고 하더라도 coverage로 포함됩니다.

 

Nest에서는 "collectCoverageFrom": ["**/*.(t|j)s"] 값인데, 어느 파일이건 ts/js면 일단 coverage 범위에 넣는군요.

 

coverageThreshold 

jestjs.io/docs/en/configuration#coveragethreshold-object

Default: undefined

 

coverage 통과 기준을 세울 수 있습니다. 특정 coverage 수치 이상을 통과하지 못한다면 경고를 해줍시다.

{
  ...
  "jest": {
    "coverageThreshold": {
      "global": {
        "branches": 50,
        "functions": 50,
        "lines": 50,
        "statements": 50
      },
      "./src/components/": {
        "branches": 40,
        "statements": 40
      },
      "./src/reducers/**/*.js": {
        "statements": 90
      },
      "./src/api/very-important-module.js": {
        "branches": 100,
        "functions": 100,
        "lines": 100,
        "statements": 100
      }
    }
  }
}

 

coverageDirectory 

Default: undefined

The directory where Jest should output its coverage files.

Nest에서는 "coverageDirectory""../coverage" 입니다.

 

coveragePathIgnorePatterns

jestjs.io/docs/en/configuration#coveragepathignorepatterns-arraystring

 

Default: ["/node_modules/"]

test coverage 대상에서 제외할 파일을 등록할 수 있습니다.

 

testEnvironment 

jestjs.io/docs/en/configuration#testenvironment-string

Default: "jsdom"

 

테스트가 진행되는 환경입니다. 기본적으로는 jsdom, 즉, dom입니다. node에서 jest를 사용하고자 하면 nede를 적어주시면 됩니다. 당연히 Nest에서는 node입니다.

 

moduleNameMapper

jestjs.io/docs/en/configuration#modulenamemapper-objectstring-string--arraystring

Test 대상이 되는 파일에서 사용하는 외부 모듈들, 이를테면 entity, 이미지, css 등을 불러올 경로를 지정합니다.

현재 nest 7.5.3 에서는 테스트 코드를 작성할 때 외부 모듈을 찾을 수 없다고 에러를 내서, 사용자가 적절히 구성해줄 필요가 있습니다.

 

"moduleNameMapper": {"^src/(.*)$": "<rootDir>/$1"}

 

Note: If you provide module name without boundaries ^$ it may cause hard to spot errors. E.g. relay will replace all modules which contain relay as a substring in its name: relay, react-relay and graphql-relay will all be pointed to your stub.


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체