테스트 커버리지 100%

2019년 1월쯤에 회사에서 만들고 있는 서버 애플리케이션의 테스트 커버리지를 100% 까지 올렸다. 그리고 1년동안 100%를 계속 유지했다.

테스트 커버리지 100%를 달성한 서버 애플리케이션은 코틀린으로 작성되어있으며, 90% 이상의 코드를 내가 작성했다. 테스트 커버리지는 jacoco로 측정했으며, branch coverage와 instruction coverage 모두 100% 를 유지했다. 다만 전체 코드 중 일부(약 2%)는 kotlin 혹은 jacoco의 한계 등의 이유로 커버리지 측정 대상에서 제외했다.

테스트 커버리지를 100%로 올려보겠다고 마음먹은 것은 2018년에 책 클린 코더를 읽다가 이런 문구를 발견해서이다. 테스트 커버리지는 어느정도나 되어야 충분할까에 대해 종종 생각하곤 했는데, 클린 코더의 답은 간단하고 단호했다.

얼마만큼의 코드를 자동화한 단위 테스트로 테스트해야 할까? 대답할 필요조차 없다. 모조리 다 해야 한다. 모.조.리!

100% 테스트 커버리지를 권장하냐고? 권장이 아니라 강력히 요구한다. 작성한 코드는 한 줄도 빠짐없이 전부 테스트해야 한다. 군말은 필요 없다.

이 주장에 완전히 동의하지는 않았지만, 그럼에도 불구하고 100%가 정말 가능한건지, 만약 실현한다면 어떤지 궁금해졌다. 예전에 오픈소스 프로젝트인 urllib3가 커버리지 100%를 유지하고 있던 것을 본 적이 있어서 가능할수도 있겠다고 생각했다. (지금 가보니 100%는 커녕 build failing 상태다) 그래서 아주 작은 프로젝트에서 시도해봤는데 실제로 해볼만 했다. 그래서 그 다음은 본격적으로 현업에서 주 업무로 진행하는 프로젝트에서도 시도해보기로 했다.

마음 먹고 가장 먼저 한 일은 현재의 커버리지를 계산한 뒤 그 밑으로는 결코 내려가지 않도록 하는 것이었다. jacoco gradle plugin 의 jacocoTestCoverageVerification gradle task를 이용해 지정된 수치 미만으로 커버리지가 떨어지면 전체 테스트가 실패로 간주하도록 했다. 그리고 테스트가 실패하면 배포가 불가능하게 했다. 이 서버 애플리케이션은 실제 서비스중이었고 수시로 배포를 해야만 했으므로 이렇게 설정하면 커버리지가 내려가는 것은 거의 불가능했다.

이렇게 한 뒤 틈틈이 커버리지를 조금씩 올리고 올릴 때 마다 커버리지 하한도 그에 맞추어 같이 올렸다. 처음은 라인 커버리지 83.9% 였다. (사실 커버리지 요구조건이 없었을 때도 그렇게 낮지는 않았다) 솔직히 100% 까지 끌어올리는 것은 상당히 어려웠다. 커버리지가 높아질 때 마다 점점 더 어려워졌다. 85%를 95%로 만드는 것 보다 95%를 99%로 만드는 것이 어렵고, 99%를 100%로 만드는 것은 그것보다도 훨씬 더 어려웠다. 언어(kotlin)의 한계와 커버리지 도구(jacoco)의 한계에 부딪혔고 우회책을 찾아야했다. 왜 커버가 안되는지 확인하기 위해 바이트 코드를 분석하기도 해야했다.

어쨌든 한달 동안 꾸준히 올리자 라인 커버리지 기준으로 100%가 되었고, 10일 정도 더 지나자 브랜치 커버리지로도 100%가 되었다. 그리고 나서 계속 테스트 커버리지 100%를 유지했다. 그렇게 1년이 지났다.

테스트 커버리지 100%를 계속 유지하는 것은 그렇게 어렵지 않았다. 처음 커버리지를 100% 까지 끌어올릴때는 상당히 고생했지만 일단 경험이 쌓이고 익숙해지니 어떻게 해야 커버가 되는지 이해(혹은 암기)하게 되었기 때문이다.

그리고 개발은 상당히 수월해졌다. 모든 코드는 언제나 테스트로 커버되기 때문에 언제 배포해도 문제없다는 자신감을 갖고 있었다. 이 자신감 덕분에 필요하면 지체없이 과감한 리팩토링을 실행할 수 있었다.

테스트 커버리지를 항상 100%로 유지해야한다고 생각하지는 않는다. 언제라도 배포할 수 있는 자신감을 얻을 수 있다면 그걸로 충분하다. 문제가 생길까봐 무서워서 리팩토링을 잘 못하고 있다면 테스트가 부족한 것일 수 있다. 그 정도의 자신감을 얻는데 필요한 커버리지가 반드시 100%는 아닐 것이다. 그럼에도 불구하고 테스트 커버리지 100% 유지를 택한 것은 다음의 이유 때문이다.

1. 책 클린 코더가 강력히 권장한 테스트 커버리지 100%가 정말로 가능한지 확인하고 싶었다.
2. 테스트 커버리지는 마음만 먹으면 얼마든지 높일 수 있다는 것을 보여주고 싶었다.
3. 90%나 95%보다 100%가 더 단순해서 유지하기 쉬운 규칙이라고 생각했다.

내가 다니는 회사는 스타트업이고 빠르게 일하는 것으로 잘 알려져있다. 이런 회사에서 서버 애플리케이션을 만드는 개발자도 테스트 커버리지 100%를 달성하고 유지하는 것은 가능했다.

다만 프로젝트 초기부터 높은 커버리지를 유지했기 때문에 가능한 것이었을지도 모른다. 어쩌면 주로 혼자서 작업했기 때문에 쉬웠을지도 모르겠다. 여럿이 함께 작업하는 오래되고 큰 프로젝트의 테스트 커버리지를 끌어올리려고 시도하는 것은 훨씬 어려울 것이다. 하지만 언젠가 기회가 되면 그것도 시도해보고 싶다.

테스트 커버리지 100%”에 대한 3개의 생각

  1. 안녕하세요, 유투브에서 발표 정말 잘 들었습니다! 발표 듣다보니 coverage 기준을 instruction으로 잡고 테스트 커버리지 높이는 작업을 하신 것 같은데요, 혹시 branch가 아닌 instruction 기준으로 coverage를 측정하신 이유가 있으실까요?

    좋아요

    1. 모든 인스트럭션이 다 실행되었는지 확인하는게 가장 확실할 것 같아서 그렇게 했었습니다. 실제로 해 보니 브랜치에선 100%라도 인스트럭션에선 100%가 안뜨는 경우가 있더라구요.

      좋아요

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중