Logo

Jest로 테스트 커버리지 수집하기

이번 포스팅에서는 테스트 커버리지(coverage)가 무엇인지 알아보고 Jest를 이용해서 테스트 커버리지를 수집하는 방법에 대해서 알아보겠습니다.

테스트 커버리지(Test Coverage)란?

테스트 커버리지(test coverage)는 코드 커버리지(code coverage)라고도 하는데요. 쉽게 말해 코드가 얼만큼 테스트되고 있는지를 나타내는 소프트웨어의 품질 지표입니다. 테스트 커버리지가 높은 소프트웨어는 버그가 발생할 확률이 적기 때문에 사용자가 좀 더 신뢰하고 사용할 수 있습니다. 당연히 반대로 테스트 커버리지가 낮은 소프트웨어는 믿고 사용하기가 좀 어렵겠죠?

Jest 명령어의 —coverage 옵션

Jest가 설치되어 있는 프로젝트라면 Jest로 테스트를 실행하면서 커버리지 데이터를 수집해볼 수 있는데요. 다음과 같이 jest 명령어를 실행할 때, --coverage 옵션만 붙여주면 됩니다.

$ npx jest --coverage

테스팅 프레임워크인 Jest에 생소하신 분들은 먼저 Jest로 기본적인 테스트 작성하기를 읽어 보시고 돌아오시기를 추천드립니다.

이렇게 jest 명령어를 실행하게 되면 평소와 다르게 터미널에 Coverage summary가 함께 나오는데요. 구문(Statements), 분기(Branches), 함수(Functions), 줄(Lines) 기준으로 코드가 얼마나 테스트되고 있는지가 퍼센트로 표시됩니다.

(...생략...)

=============================== Coverage summary ===============================
Statements   : 95.74% ( 494/516 )
Branches     : 78.25% ( 403/515 )
Functions    : 93.44% ( 114/122 )
Lines        : 95.67% ( 486/508 )
================================================================================

Test Suites: 29 passed, 29 total
Tests:       217 passed, 217 total
Snapshots:   1 passed, 1 total
Time:        26.702 s

뿐만 아니라 프로젝트 최상위 경로에 coverage라는 디렉토리가 생성된 것도 볼 수 있을텐데요. 그 폴더에 들어가면 수집된 커버리지 데이터에 대한 다양한 형식의 리포트(report)를 확인해볼 수 있습니다.

예를 들어, 커버리지를 리포트를 웹페이지 형태로 보고 싶다면 브라우저에서 coverage/lcov-report/index.html 파일을 열어보면 됩니다.

커버리지 수집 범위 설정

위와 같이 별도의 추가 설정없이 Jest로 커버리지 데이터를 수집하면 예상했던 것보다 커버리지 결과가 높게 나와서 놀라는 경우가 있는데요. 이것은 Jest가 기본적으로 프로젝트의 전체 코드를 대상으로 커버리지를 수집하는 것이 아니라, 이미 테스트가 있는 코드만을 대상으로 커버리지를 수집하기 때문입니다.

따라서 좀 더 정확한 커버리지 분석 결과를 얻으려면 collectCoverageFrom 옵션을 사용하여 커버리지 수집 범위를 설정해줘야 합니다.

jest.config.js
module.exports = {
  collectCoverageFrom: ['**/*.[jt]s?(x)', '!**/*.stories.[jt]s?(x)'],
};

위와 같이 설정하면, 파일 이름에 stories가 들어간 파일을 제외한 프로젝트 내의 모든 자바스크립트와 타입스크립트 파일에 대해서 커버리지 데이터가 수집될 것입니다.

커버리지 최소 기준 설정

테스트 커버리지를 중요시하는 프로젝트에서는 새롭게 작성한 코드가 프로젝트에서 약속한 커버리지 기준에 만족하는지 체크하는 경우가 많은데요. coverageThreshold 옵션을 통해서, 구문(Statements), 분기(Branches), 함수(Functions), 줄(Lines) 기준으로 최소 커버리지를 지정해줄 수 있습니다.

예를 들어, src 디렉토리에 대해서 최소 커버리지를 상당히 높게 잡아보겠습니다.

jest.config.js
module.exports = {
  coverageThreshold: {
    './src/': {
      statements: 95,
      branches: 90,
      functions: 95,
      lines: 90,
    },
  },
};

동일한 프로젝트를 대상으로 jest 명령어를 --coverage 옵션과 함께 실행하면 다음과 같이 커버리지 기준을 맞추지 못했다는 에러가 발생하게 됩니다.

(...생략...)

=============================== Coverage summary ===============================
Statements   : 95.74% ( 494/516 )
Branches     : 78.25% ( 403/515 )
Functions    : 93.44% ( 114/122 )
Lines        : 95.67% ( 486/508 )
================================================================================
Jest: "./src/" coverage threshold for branches (90%) not met: 78.25%Jest: "./src/" coverage threshold for functions (95%) not met: 93.44%
Test Suites: 29 passed, 29 total
Tests:       217 passed, 217 total
Snapshots:   1 passed, 1 total
Time:        22.275 s

이 명령어를 CI(Continuos Integration)나 CD(Continuos Delivery)를 통해 실행해준다면 커버리지 기준에 미달하는 코드가 코드 저장소에 유입되는 것을 방지할 수 있을 것입니다.

커버리지 보고 형식 설정

테스트 커버리지 분석 결과는 다양한 형식으로 보고서를 만들어 낼 수 있는데요. Jest는 기본적으로는 4가지 형식으로 보고서를 만들어주지만, coverageReporters 옵션을 통해 특정 파일 형식으로만 보고서를 만들어 낼 수 있습니다.

jest.config.js
module.exports = {
  coverageReporters: ['lcov', 'text'],
};

대규모의 프로젝트에서는 이 방법을 통해 불필요한 보고서를 줄이고 Jest 명령어 수행 시간을 단축할 수 있습니다.

커버리지 명령어 npm 스크립트 등록

참고로 협업 프로젝트에서는 커버리지를 수집하는 명령어를 npm 스크립트로 등록해두는 것을 추천드립니다.

package.json
{
  "scripts": {
    "test": "jest",
    "coverage": "jest --coverage"
  }
}

그러면 Jest에 생소한 팀원들도 큰 어려움없이 해당 명령어를 실행할 수 있겠죠?

$ npm run coverage

자바스크립트 프로젝트에서 자주 사용되는 명령어인 npm run에 대한 자세한 설명은 관련 포스팅을 참고 바랍니다.

마치면서

지금까지 Jest를 이용하여 어떻게 테스트 커버리지 데이터를 수집하고, 관련해서 어떤 설정을 해줄 수 있는지에 대해서 알아보았습니다. 테스트 커버리지를 잘 관리하셔서 많은 사람들이 믿고 쓸 수 있는 소프트웨어를 개발하실 수 있으셨으면 좋겠습니다.

Jest에 연관된 포스팅은 Jest 태그를 통해서 쉽게 만나보세요!