상세 컨텐츠

본문 제목

Codecov로 테스트 커버리지 측정 및 자동화 (Jest, CircleCI)

개발

by 호박너구리의 블로그 2021. 5. 30. 14:49

본문

 

이제까지 Jest를 통해 테스트를 적용하기는 했으나, 강제성이 없고 스스로 커버리지를 따로 확인해야만 한다는 아쉬움이 있었습니다. 그래서 커버리지를 꾸준히 트래킹하고 쉽게 확인하기 위해 test coverage 툴 중의 하나인 Codecov를 적용했습니다.

 

 

Code Coverage 툴을 사용하는 이유

위에서 간단히 언급했지만, 자세히 설명하자면 코드 커버리지 툴을 통해 다음과 같은 이득을 얻을 수 있지 않을까 생각했습니다.

  1. Code coverage 트래킹
    • (jest --coverage를 사용하면 coverage를 확인할 수는 있으나) 값의 변화를 트래킹하고 보다 시각적으로 잘 확인하기 위해서
  2. pull request에서 coverage 확인
    • 의도적으로 커버리지를 찾지 않더라도 평소에 자연스럽게 coverage를 확인하고 신경쓰게 되도록

 

⇒ 결과적으로, 다음과 같은 테스트의 장점들을 누리기 위해서 (= 테스트 코드를 장려하기 위해서) Code Coverage를 사용하려고 하는 셈이죠!

  1. 코드 리뷰가 쉬워짐
    • 코드가 이해가 안되면 테스트 코드를 확인하면 됨. 코드는 어떤 기능이고, 어떻게 사용되고, 주의해야 할 점이 무엇인지 더 쉽게 파악할 수 있음.
  2. 코드 수정이 쉬워짐
    • 코드를 잘못 수정했을 때 테스트를 통해 미리 확인할 수 있다는 믿음이 생김.

(+ TDD의 강점에 대해서는 말을 많이 들었는데, 사실 테스트 코드를 미리 쓰고있지는 않아서 아직 이점을 느끼지는 못했습니다)

 

 

 

Code Coverage Solution 선택하기

  • codecov vs coveralls

코드 커버리지 관리를 위한 툴에는 크게 codecovcoveralls 가 있습니다. 둘 다 pull request, commit status, 알림, 커버된 소스코드 보기 등의 기본적인 기능은 잘 지원합니다.

다만 codecov가 문서 설명이 훨씬 잘되어있고, customization에 훨씬 용이합니다. coveralls는 설정 파일에 인증을 위한 토큰밖에 넣지 못하는데 codecov는 여러 커스텀이 가능합니다.

(codecov의 단점은 팀원이 많은 경우 비용이 훨씬 비싸다는 것 정도입니다)

 

그럼 본격적으로 codecov를 사용해보겠습니다!

 

 

[Codecov 시작하기]

1. codecov.io 에서 로그인하고 연동

codecov의 주소로 들어가면 바로 깃허브(혹은 bitbucket) 계정으로 연동할 수가 있습니다.

이미지는 계정에 속한 리포를 확인하는 화면인데 organization과 연동하면 해당 조직에서 소유한 org를 확인할 수 있습니다. (아래 repo 목록이 뜨는데 가리기 번거로워서 윗부분만 캡쳐했습니다)

 

이후 원하는 repo를 고르면 됩니다!

 

※ organization에 속한 repo라면?

organization에 속한 Repo에 처음에 들어가면 activate되지 않았다는 화면이 보일텐데요, 화면에 파랑 글자로 보이는 activate this repository를 누르면 됩니다. 그럼 settings로 이동하게 되고 activate하면 탭 구성이 바뀌게 됩니다.

 

그러면 이제 토큰이 적혀있는 화면이 나타나게 됩니다! public 리포에는 토큰이 필요없지만, private 리포는 토큰이 있어야 합니다! 토큰 적용은 아래서 이어서 확인해볼게요.

해당 화면에 토큰 정보가 보입니다.

 

2. 패키지 다운로드

우선 codecov 패키지를 다운받습니다.

npm install codecov --save-dev // yarn add --dev codecov

 

 

이제 제가 주로 사용하는 (JS나 React 등을 테스트하기 위한) Jest에 적용해보겠습니다!

 

 

[Jest에서 Codecov 적용하기]

1. 설정하기

  • jest를 사용하고 있음을 가정한 설명입니다. 아직 jest를 설치하지 않았다면 테스트 관련 문서를 먼저 참조해주세요.

첫 설정을 위해 다음과 같은 명령어를 입력해줍니다.

jest --ci --coverage && codecov

 

※ 여기서 command not fount: jest 에러가 발생한다면?

./node_modules/.bin/jest --ci --coverage && ./node_modules/.bin/codecov

이는 아마 global하게 설치되지 않아서 명령어를 바로 사용하지 못하기 때문입니다. 그 경우 명령어는 ./node_modules/.bin에 설치되어 있을 것이기에 명령어들 앞에 해당 글자를 추가하면 됩니다.

 

이제 디렉토리를 보면 coverage라는 폴더가 생성되어 있을 것입니다.

 

2. 작동시키기

앞으로 테스트를 하고 코드 커버리지를 업데이트 하기 위해 명령어를 스크립트로 만들어 두겠습니다.

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

 

그리고 한 번 명령어를 실행해보겠습니다.

yarn test-codecov

 

그럼 jest가 돌고나서 codecov가 도는 것을 확인할 수 있을 것입니다.

 

그리고 처음에 접속했던 사이트에 들어가서 확인해보면 아마 다음과 같은 Overview 화면을 볼 수 있을 것입니다!

 

※ 만약 업데이트 되지 않았다면?

public repo라면 codecov.io의 메인화면 overview 탭이 달라진 것을 확인하실 수 있겠지만, private repo를 사용한다면 아직 한 가지 스텝이 더 남아있습니다. 바로 토큰을 적용해야 하는 것이죠

 

3. 토큰 적용하기

  • 토큰은 overview 탭이나 settings 탭에서 확인하실 수 있습니다.

토큰을 적용하려면 다음 명령어를 입력하시면 됩니다.

export CODECOV_TOKEN=":uuid-repo-token"
# or
./node_modules/.bin/codecov --token=:token

 

 

그리고 다시 codecov를 작동하면 리포트가 업로드되고 커버리지가 업데이트 된 것을 확인할 수 있습니다.

yarn test-codecov

 

 

※ 깃훅에 따라 자동화하고 싶다면?

저는 push할때마다 coverage를 업데이트 하도록 husky pre-push 깃 훅에 해당 스크립트를 적용하였습니다.

만약 husky나 깃훅 액션 자동화 적용을 모르시거나 적용이 안되어있다면, 관련 포스트를 참고해주세요

npx husky add .husky/pre-push 'yarn test-codecov'

 

 


아래는 CircleCI나 깃허브와 연동하는 방법입니다

[CI에 달기: CircleCI]

만약 브랜치가 push될 때마다 작동되기를 원한다면 CI/CD에 연동하면 됩니다!

기존에 circleCI를 쓰고 있다면 어렵지 않게 추가할 수 있습니다.

 

1. circleCI 설정 추가: config.yml

codecov에서는 쉽게 적용할 수 있도록 orb를 제공하고 있는데요, 그걸 사용하면 됩니다.

(아래 코드 중에서 run: yarn test-coveragecodecov/upload 부분이 핵심이며 그 위의 코드는 패키지 설치나 캐싱등의 기본 설정입니다)

version: 2.1
orbs:
  codecov: codecov/codecov@1.0.2
jobs:
  test-and-check-coverage:
    docker:
      - image: circleci/node:lts
    steps:
      - checkout
      - restore_cache:
          key: dependency-cache-live-{{ checksum "package.json" }}
      - run: yarn
      - save_cache:
          key: dependency-cache-live-{{ checksum "package.json" }}
          paths:
            - ./node_modules
            - ./.next/cache
      - run: yarn test-coverage
      - codecov/upload:
          file: './coverage/clover.xml'

workflows:
  test-application:
    jobs:
      - test-and-check-coverage

 

2. project에 환경 변수 추가

circleCI 앱 사이트에서 프로젝트 환경변수에 토큰을 추가해주어야 합니다.

CODECOV_TOKEN 이라는 key로 저장하기만 하면 간단하게 끝이죠!

 

 

3. circleCI 동작

그럼 한 번 푸시해서 circleCI를 동작시켜 보겠습니다.

잘 작동하나요? 테스트가 통과되고 circleCI가 패스한다면 성공한 것입니다!

 

※ Orb관련해서 에러가 난다면?

circleCI 전체 설정(Organization Settings → Security)에서 제3자의 Orb(Allow Uncertified Orbs)도 수용한다고 Yes에 체크해야 합니다

 

 jest나 coverage 관련해서 에러가 난다면?: jest에 설정 추가

// package.json 이라면
"jest": {
  coverageDirectory: "./coverage/",
  collectCoverage: true
}

// jest.config.js 라면
module.exports = {
  ...
  coverageDirectory: "./coverage/",
  collectCoverage: true
}

 

 테스트(jest)가 로컬에서는 성공하는데 CircleCI에서 오류가 난다면?

ENOMEM: not enough memory: 그냥 jest로 스크립트 yarn test / npm run test를 썼다면 -w 1 옵션을 추가해서 시행합니다. (jest -w 1)

참고자료: green_heart:(Circle CI): Not Enough Memory · zcorky/moment@dd9ebd8

 

 다른 이유로 jest에 오류가 발생한다면?: 아래 글 참조

참고자료: Why Do My Tests Pass Locally but Fail on CircleCI?

 

 

[깃허브에 연동하기]

처음 목적이 깃허브에서 풀리퀘를 날릴 때 커버리지를 확인하기 위함이었죠. codecov 봇과 연동하면 풀리퀘에서 coverage 상황과 변화를 측정해주는데요, 방법은 어렵지 않습니다.

 

우선 루트에 .codecov.yml 파일을 추가합니다.

status:
  project: yes
  patch: yes
  changes: no
  • Codecov patch : 내 브랜치에 수정한 코드를 현 테스트로 얼마나 커버할 수 있는지 확인합니다.
  • Codecov project : 내가 만든 브랜치를 마스터에 합쳐서 현 테스트 코드로 얼마나 커버할 수 있는지 확인합니다.

 

그리고 풀리퀘를 만들면 다음과 같이 봇이 적용되는 것을 볼 수 있습니다!

 

비록 지금은 커버율이 40%도 안되지만, 이제 커버리지를 확인하며 테스트 코드를 작성하다보면 점점 높여나갈 수 있겠죠??

728x90

관련글 더보기

댓글 영역