monorepo에서 테스트 작성하기

Inhye Jeong·2021년 9월 15일
0

monorepo에서 unit 테스트만 필요한 workspace가 있고, e2e 테스트만 필요한 workspace가 있습니다.
이에 대한 구성을 jest, yarn workspace, next.js 기준으로 작성합니다.


1. monorepo 에서 테스트

1) jest.projects 옵션을 사용해서 root에서 테스트한다.

Organizing tests with jest projects - 🚀 Jakub Homoly

  • root의 jest.config.js에서 jest의 projects옵션을 사용하여 root에서 test script를 실행한다.
// jest.config.js
module.exports = {
  projects: [
    '<rootDir>/monorepo/admin/jest.config.js',
    '<rootDir>/packages/*/jest.config.js',
  ],
}
  • root에서 test를 실행하기 때문에 root에서 jest를 가지고 있다.

  • workspacejest.config.js, babel plugin과 같이 필요한 library만을 가지고 jest를 가지고 있지 않는다.

2. babel 플러그인의 이해

1) babel이 jest에서 필요한 이유

  • jest는 javascript 테스트 도구이다.

    • 따라서 ts 로 테스트를 작성하고 실행하려면 babel을 통해 js로 변환해야한다.
  • jest는 cjs 모듈 시스템을 사용한다.

    • 따라서 es6문법인 import/export를 사용하면 에러가 발생하므로 bable을 통해 cjs로 변환해야한다.

2) 필요한 plugin들

  • babel/preset-typescript : jsts로 변환시켜주는 Plugin들의 집합이다.
  • babel/preset-env : js 문법을 cjs로 맞춰주는 Plugin들의 집합이다. ex) es6 → es5

참고 : Next에서는 내부적으로 ts 사용을 위해 next/babel을 사용중이므로 babel을 커스터마이징 하기 위한 것이 아니면 babel을 추가 설치하지 않아도 된다.

3) ts-jest

  • babel7에서 이미 @babel/preset-typescript를 제공하지만, 타입체킹에서 한계가 존재한다. 이를 대체할 ts-jest라는 package를 사용해도 좋다.
//jest.config.js
module.exports = {
  ..
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
  },
  ..
};
  • ts-jest를 사용한다면, preset: 'ts-jest/presets/js-with-ts'2)번의 두 가지를 대체한다.
  • Jest 24부터 Babel 6에 대한 지원을 중단함. 따라서 Babel 7을 사용하는 것이 권장됨. Babel 7을 사용하면 babel-jest를 따로 설치할 필요가 없다.

Jest 24 dropped support for Babel 6. We highly recommend you to upgrade to Babel 7, which is actively maintained. However, if you cannot upgrade to Babel 7, either keep using Jest 23 or upgrade to Jest 24 with babel-jest locked at version 23, like in the example below:

3. tsconfig의 이해

각 workspace 별로 e2e, unit 테스트 등 필요한 tsconfig가 다를 수 있습니다. 우선 next.js에서 e2e 테스트 시, 수정해줘야했던 옵션들에 대해 설명합니다.

TSConfig Reference - Docs on every TSConfig option

1) compilerOptions.jsx란?

  • jsx 프로퍼티란 jsx코드를 어떻게 컴파일할지 결정한다.

    • 이는 오직 .tsx 확장자의 컴파일 결과에만 영향을 준다.
  • jest는 cjs 모듈 시스템을 사용하므로 .js파일로 변환하기위해 아래 옵션 중, "react”를 필요로한다. 이것은 React.createElemet()를 사용하므로 react를 반드시 import해주어야한다.

react : .js 파일로 컴파일 된다. (JSX 코드는 React.createElement() 함수의 호출로 변환됨)
react-jsx : .js 파일로 컴파일 된다. (JSX 코드는 _jsx() 함수의 호출로 변환됨)
react-jsxdev : .js 파일로 컴파일 된다. (JSX 코드는 _jsx() 함수의 호출로 변환됨)
preserve : .jsx 파일로 컴파일 된다. (JSX 코드가 그대로 유지됨)
react-native : .js 파일로 컴파일 된다. (JSX 코드가 그대로 유지됨)

2) next.js에서 test를 위한 tsconfig 설정하기

2.1)과 3.1)에서 설명했던 것과 같이 jest는 cjs시스템을 사용하므로 tsx를 js로 컴파일 해줘야 한다. 따라서 e2e테스트를 하려면 jsx 옵션 중 "react"를 설정해야한다.

하지만 next.js는 자체적으로 최적화된 jsx transform을 구현하고 있으므로

  • jsx 옵션 중 "preserve"를 유지해야한다.
  • e2e테스트를 하기 위해, jsx 옵션 중 "react"를 설정한 test용 tsconfig.test.json이 필요하다.
  • jsx was set to preserve (next.js implements its own optimized jsx transform)
  • 참고 이슈
  • jsx 옵션을 수정해도 next build시 preserve로 자동 변환되어 버린다.
// tsconfig.test.json
"compilerOptions": {
  ..
  "jsx": "react"
},
  • next.js 앱 root의 jest.config.js에서 tsconfig.test.jsontsConfig로 설정해주자.
// jest.config.js
module.exports = {
  ..
  preset: 'ts-jest/presets/js-with-ts',
  globals: {
    'ts-jest': {
      tsConfig: '<rootDir>/tsconfig.test.json',
    },
  },
}

ref

profile
Frontend Engineer in @KakaoStyle

0개의 댓글