요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

글을 시작하기 앞서, ‘테스트’라는 낱말이 매우 보편적으로 쓰이기 때문에 이 글에서 말하는 테스트가 무엇인지 정의할 필요가 있다. 이 글에서 ‘테스트’는 개발자가 코드로 작성하고 코드를 실행하여 자동으로 테스트를 수행하는 것을 뜻한다. 요즘은 테스트 코드를 작성하는 것 자체가 논쟁 대상이 되지 않을 정도로 많은 개발자들(조직)이 테스트에 관심을 가지고 테스트를 작성한다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

개발자여, 테스트 커버리지에 집착 말자

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

글을 시작하기 앞서, ‘테스트’라는 낱말이 매우 보편적으로 쓰이기 때문에 이 글에서 말하는 테스트가 무엇인지 정의할 필요가 있다. 이 글에서 ‘테스트’는 개발자가 코드로 작성하고 코드를 실행하여 자동으로 테스트를 수행하는 것을 뜻한다. 요즘은 테스트 코드를 작성하는 것 자체가 논쟁 대상이 되지 않을 정도로 많은 개발자들(조직)이 테스트에 관심을 가지고 테스트를 작성한다.

 

개발자가 만든 테스트 코드를 측정하는 방법으로 보통 테스트(코드) 커버리지를 사용한다. 커버리지 지표는 테스트 코드가 코드 베이스를 얼마나 실행하는지 백분율로 나타낸 것이다.

출처: <단위 테스트>

 

테스트 커버리지는 시각적이며 정량적이다. 그래서 사람들은 커버리지가 높으면 좋고 낮으면 안 좋다는 이분법의 함정에 쉽게 빠진다. 그리고 나는 이런 함정 속에서 높은 커버리지에 집착해 커버리지를 높이려고 과도한 행위를 하는 사람들을 본다.

 

출처: 작가

 

<도메인 주도 설계>의 저자 에릭 에반스는 그의 책에서 소프트웨어의 본질이 ‘사용자를 위해 도메인에 관련된 문제를 해결하는 능력’이라 말한 바 있다. 커버리지를 높이기 위해 시도하는 과도한 행위는 소프트웨어가 해결하고자 하는 본질을 가린다.

 

소프트웨어의 본질은 해당 소프트웨어의 사용자를 위해 도메인에 관련된 문제를 해결하는 능력에 있다. 그 밖의 매우 중요하다 할 수 있는 기능도 모두 이러한 기본적인 목적을 뒷받침하는 데 불과하다. - <도메인 주도 설계>

 

이 글은 테스트 커버리지에 대한 과도한 집착이 만드는 높은 커버리지의 이면을 다룬다.

 

테스트 커버리지는 테스트 되지 않은 부분을 알려 줄 뿐

상관관계와 인과관계라는 것이 있다. 전자는 두 변수가 얼마나 상호 의존적인지를 뜻하며, 후자는 실질적으로 하나의 요인으로 인해 다른 요인의 수치가 변하는 형태처럼, 원인과 결과 관계가 명확한 것을 뜻한다.

 

일반적으로 테스트 커버리지와 코드 품질은 상관관계가 나타난다. 그래서 사람들은 테스트 커버리지가 높으면 자연스럽게 코드 품질 역시 높을 것이라고 생각하는 경향이 있다. 하지만 상관관계는 인과관계가 아니다. 커버리지가 높다 해서 꼭 코드 품질이 높은 것은 아니라는 말이다. 코드 품질은 그렇게 쉽게 측정할 수 있는 것이 아니기 때문이다. 마틴 파울러가 그의 에서 말하듯이 테스트 커버리지는 테스트 되지 않은 부분을 알려 줄 뿐이다.

출처: 마틴 파울러 블로그

 

QA가 기능 테스트를 한다고 가정해 보자. 엉터리 시나리오로 테스트했다면, 기능은 테스트 되었지만(커버) 실제로 품질이 높다고 할 수 없다. 커버리지 지표가 코드 품질에 영향을 미치려면 테스트 코드가 테스트 대상을 얼마나 정확하게 테스트하고 있는지 검증해야 한다.

 

 

테스트 커버리지 집착이 부르는 문제

내가 참여했던 프로젝트에서는 커버리지가 80%가 조금 넘는 모듈이 있었다. 모듈 담당자는 커버리지를 90%까지 올리겠다며 사람들 앞에서 공언하며 시간을 썼다. 테스트 코드 작성 경험이 있는 사람들은 알겠지만 커버리지는 어느 정도까진 올리기 쉽지만  그 정도를 넘어서면 올리기가 어렵기 때문에 많은 시간과 노력이 필요한 일이다.

 

숫자(커버리지 지표)가 주는 효과는 대단하다. 사람들에게 명확하고 정확하게 설명할 수 있고 시쳇말로 ‘뇌피셜’도 아니어서 반박하기도 쉽지 않다. 하지만 19세기 영국 정치가 디즈레일리(Benjamin Disraeli)가 말했다고 전해지는 “세상에는 세 가지 종류의 거짓말이 있다. 거짓말과 새빨간 거짓말, 그리고 통계다”라는 말을 기억해 둘 필요가 있다. 구체적인 숫자를 언급할수록 유의해서 받아들여야 한다는 뜻이다.

 

눈에 보이는 수치에 집착하면 중요한 것을 보지 못한다. 커버리지를 올리기 위해 도메인 연관성이 떨어지거나 상관도 없고 중요하지도 않은 단순한 코드까지 테스트해야 할 수도 있으며, 심지어 내가 만들지 않은 영역까지 해야 할 수도 있다. 이런 행위는 사용자를 위해 도메인에 관련된 문제를 해결한다는 소프트웨어의 본질과 거리가 있다. 커버리지 지표가 목표가 되어버린다면 이미 중요한 것을 놓치고 있는 것이다.

 

특정 커버리지 숫자를 목표로 하는 것은 단위 테스트의 목표와 반대되는 그릇된 동기 부여가 된다. 사람들은 중요한 것을 테스트하는 데 집중하는 대신 인공적인 목표를 달성하기 위한 방법을 찾기 시작한다. 적절한 단위 테스트는 이미 충분히 어렵다. 커버리지 숫자를 강요하면 개발자들은 테스트 대상에 신경 쓰지 못하고, 결국 적절한 단위 테스트는 더욱 달성하기 어려워진다. <단위 테스트, 생산성과 품질을 위한 단위 테스트 원칙과 패턴>

 

앞서 언급한 모듈 담당자는 특정 커버리지 숫자를 목표로 삼았으며, 인공적인 목표를 달성하기 위해 중요하지 않은 것을 테스트하는 방법을 찾았다. 함정에 빠진 것이다. 결과적으로 그는 그의 공언과는 달리 목표를 달성하지 못했으며, 그의 판단과 행동은 프로젝트에 아무런 도움이 되지 못한 채 흐지부지 끝나고 말았다.

 

 

테스트는 중요한 곳에 집중해야 한다

여기까지 글을 읽은 독자라면 내가 “테스트 코드를 많이 작성하지 마라”라고 주장하는 것으로 오해할 수 있겠다. 다시 한번 말하지만 커버리지를 올리기 위한 인공적인 목적으로 과도한 테스트 코드를 작성하는 것을 경계하라는 의미이다.

 

우리는 날마다 코드를 고친다. 그렇기에 테스트가 프로젝트 생산성과 지속성에 도움이 되려면 코드 변경 후 개발자에게 큰 문제가 없다는 확신을 주어야 한다. 여기서 말하는 ‘큰 문제’는 비즈니스 도메인과 각자가 처한 상황에 따라 다르다. 하지만 ‘큰 문제’가 되는 곳이 바로 테스트를 집중해야 하는 중요한 곳이다. 나는 모든 코드를 테스트해야 한다고 생각하지 않는다. 테스트는 중요한 곳에 집중해야 하고 개발자에게 큰 문제가 없다는 확신을 주어야 한다.

 

그렇다면 집중해야 할 중요한 곳은 어디일까? 코드 관점에서 생각해 보자. <단위 테스트>의 저자는 코드 유형을 ‘복잡도 및 도메인 유의성’, ‘협력자의 수’를 기준으로 네 가지로 분류하고 있다.

 

출처: <단위 테스트>

 

경험적으로 ‘간단한 코드’나 ‘컨트롤러’*에서 발생하는 문제보다는 ‘도메인 모델 및 알고리즘’이나 ‘지나치게 복잡한 코드’에서 발생하는 것이 더 큰 문제인 경우가 많다. 왜냐하면 복잡성이 높은 곳에 인지 부하로 인해 버그가 생길 가능성이 높고, 비즈니스 로직이 존재하는 도메인 모델 혹은 알고리즘에 문제가 생기면 단순히 시스템 오류로 끝나지 않기 때문이다. 그래서 나는 ‘간단한 코드’는 테스트하지 않고 ‘컨트롤러’는 간단하게 테스트하며 ‘도메인 모델 및 알고리즘’이나 ‘지나치게 복잡한 코드’에 집중한다.

* 애플리케이션 서비스와 같이 비즈니스 로직이 없고 단순히 다른 협력자들(예. 객체)을 호출하여 구성하는 역할을 하는 것을 말한다

 

 

커버리지 숫자를 목표로 삼아서는 안된다

나는 <TDD, 실패하는 테스트부터 작성해 얻는 것 5가지>라는 글에서 ‘테스트할 시간이 없다’는 죽음의 나선에서 대해 말했다. 스트레스를 받으면 점점 테스트를 덜 하게 되고 테스트를 덜 할수록 에러는 더 많이 발생할 것이며 에러가 많아지면 더 많은 스트레스를 받게 된다는 것이다. 죽음의 나선은 코드베이스가 늘어나고 시간이 지남에 따라 종국에는 개발자 생산성을 떨어뜨린다.

 

출처: 작가

 

프로젝트 지속성과 생산성을 유지하는 데 테스트가 긍정적인 영향을 미치려면 커버리지가 아니라 테스트 코드 품질에 집중해야 한다. 예를 들면 테스트 코드 품질을 저해하는 원인으로거짓 양성(1종 오류)이 있다. 실제로는 음성인데 검사 결과는 양성이라고 나오는 것을 뜻하는데, 테스트 관점에서는 테스트 대상은 문제없이 동작(음성)하지만 테스트 코드는 실패(양성) 하는 것이다. 거짓 양성은 테스트 대상의 구현된 세부 사항을 테스트 코드가 검증할 때(화이트 박스 테스트) 잘 나타난다. 이러한 거짓 양성은 개발자에게 허위 경보로 작용하고 테스트에 대한 신뢰를 떨어뜨린다.

 

테스트 코드 품질을 높이는 일은 쉽지 않은 일이다. 하지만 그럴수록 점진적인 접근이 필요하다. 앞서 예로든 거짓 양성은 테스트의 정확도를 높이는 일이기 때문에 처음부터 목표로 삼으면 달성하기 어렵다. 따라서 처음에는 ‘회귀 방지’*를 목표로 삼고, 테스트가 도움이 된다고 느낀다면 그다음 단계로 테스트 정확도를 높이는 일을 할 수 있다.

*회귀 방지(Software regression)는 소프트웨어 버그의 일종으로 코드를 변경한 후 이전에 작동하던 기능이 멈추는 것을 뜻한다.

 

이쯤에서 테스트는 얼마나 작성해야 하는지에 대한 고민이 있을 수 있겠다. 물론 각자가 처한 맥락(비즈니스, 조직, 기술, 역량 등)마다 천차만별일 것이다. 여기서 명확한 것은 남의 기준이 내게는 맞지 않는다는 것이다. 그런 의미에서 <TDD는 죽었는가?>라는 글에서 마틴 파울러가 한 말에 귀 기울일 필요 있다.

 

만약 당신이 코드를 자신 있게 변경할 수 없다면, 당신의 테스트는 (혹은 좋은 테스트) 충분하지 못하다는 것을 의미합니다. 지나치다는 신호는 당신이 코드를 변경할 때, 코드를 변경하는 것보다 테스트를 변경하는 노력이 더 많이 든다고 느낄 때를 말하는 거죠.

 

‘적정 기술(Appropriate technology)’이라는 개념이 있다. ‘적당한 기술, 알맞은 기술’이라는 말로, 해당 지역의 자원을 활용해서 누구나 쉽게 문제를 해결할 수 있는 기술을 말한다. 먼저 자신이 처한 맥락을 파악하고 자신에게 맞는 적정한 기술과 기준을 도입해야 하는 것이다.

 

출처 : <적정기술은 ‘인간’의 얼굴을 한 ‘기술’> 기사

 

나는 커버리지를 문제를 인지하는 리트머스 시험지로 사용한다. 커버리지가 낮으면 코드베이스에 테스트하지 않는 코드가 많다는 뜻이다. 잠재적인 위험을 알리는 징후다. 하지만 커버리지는 문제가 발생할 수 있다고 알려 주는 시발점일 뿐이다. 앞서 언급한 것처럼 커버리지가 낮다고 인공적인 목표를 세워 무턱대고 올려야 할 대상은 아니다. 먼저 우리에게 중요한 코드가 무엇인지 식별하고 집중해야 하며, 테스트 코드 품질을 높이는 노력을 해야 프로젝트의 지속성과 생산성을 유지할 수 있다.

 

요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

좋아요

댓글

공유

공유

댓글 2
실수투성이 개발자의 성장 이야기
151
명 알림 받는 중

작가 홈

실수투성이 개발자의 성장 이야기
151
명 알림 받는 중
솔루션 회사를 시작으로 컨설팅 회사 그리고 서비스 회사를 거쳐 지금은 스타트업에서 개발자로 일하고 있습니다. 주로 오픈소스 제품 개발, 기술 자문 및 코칭을 하고 있으며 기술과 인간의 상호작용에 관심이 많습니다.

좋아요

댓글

스크랩

공유

공유

요즘IT가 PICK한 뉴스레터를 매주 목요일에 만나보세요

요즘IT가 PICK한 뉴스레터를
매주 목요일에 만나보세요

뉴스레터를 구독하려면 동의가 필요합니다.
https://auth.wishket.com/login