IT/개발로그

단위 테스트는 왜 해야할까

김솔샤르 2022. 2. 27. 18:50

회사를 옮기고 나서 처음 놀랐던 순간은 테스트 코드를 봤을때였다. 복잡한 비즈니스 로직을 다루면서도 테스트 디렉터리가 말끔히 비워져 있었다. 코드 레벨의 자동화된 단위 테스트보다는 e2e 테스트에 의존하고 있었으며 그래서 초래되는 문제도 적지 않아 보였다. 당연하게도(?) 팀원들은 테스트 코드의 필요성에 대해서 깊이 공감하지는 못하고 있었다.

 

우선 그들을 설득할 필요가 있어보였는데, 만약 누군가 나에게 왜 꼭 단위 테스트를 해야하는지를 묻는다면 뭐라고 대답할지를 생각해보았다. 내가 그동안 느낀바로는 다음과 같은 이유들이 있다.

 

개발자 버전의 요구사항 문서

테스트 코드를 작성하면 서비스가 충족해야하는 요구사항을 명문화해 볼수 있다. 개발자라면 요구 사항을 잘못 이해하여 일어난 대참사를 직간접적으로 경험해본적이 있을 것이다. 아래 짤과 같이 말이다.

이같은 참사를 막기 위해서는 요구사항을 명확히 하는 것이 중요하다. 위 예시는 개발자가 요구사항을 명료하게 이해하지 못하여(혹은 요구사항이 구체적이지 않았거나), 기획자의 의도와는 다르게 머리를 회전시켜 나는 끔찍한 비둘기가 탄생한 것이다.

 

테스트 코드를 작성하면 개발자 버전의 요구사항 문서를 만들 수 있고 이것이 생각보다 많은 장점을 발휘한다. 먼저 하나의 코드를 여러가지 다른 방식으로 실행해 볼 테스트 케이스를 생각하게 된다. 일단 코드부터 짜서 돌려보자는 식일 때는 맹목적으로 하나의 Working Scenario만을 머릿속에 넣고 개발을 하기 쉽지만, 테스트 코드를 작성을 병행한다면(꼭 TDD를 염두한 것은 아니다) 여러 가지 시나리오를 생각해 볼 수 있고 요구사항을 구체화하는데 도움이 된다.

 

만약 다른 개발자들과 함께 작업을 한다면 테스트 코드를 통해 서로 이해한 요구 사항에 대해 체크해볼 수도 있다.

 

코드 해설서

나는 클린 코드를 꽤 좋아하는 편이지만 복잡한 도메인 로직에 번번히 무너지는 경험을 한다. 많은 다른 개발자들도 비슷할 것이고 그렇기 때문에 누군가가 작성한 코드를 이해해야만 하는 상황이라면 가끔 괴로울때도 있다. 그런데 만약 운이 좋게도 테스트 코드가 꽤 충실하게 작성되어 있다면, 어떤 의도로 작성된 코드인지 이해하는데 꽤 많은 도움이 된다.

 

심지어 테스트 코드는 미래의 나에게도 도움을 준다. 필연적으로 지금 내가 작성한 코드의 독자 중 하나는 미래의 나일 것이다. 미래의 내가 더 빠르고 명확하게 소스를 파악할 수 있도록 테스트 코드를 정성껏 작성하자.

 

 

리팩토링할 용기

자동화된 테스트는 개발자에게 '잘 돌아가던' 코드를 기꺼이 수정할 용기를 준다. 특정 기능을 검증하는 테스트가 존재한다면 코드를 과감하게 고칠 수 있다. 코드를 수정하고 나서 테스트 코드가 다시 잘 작동하는지를 확인하면 된다. 촘촘하게 작성된 테스트 케이스가 있다면(물론 어려운 일이긴 하다) 중복을 제거하고, 코드를 더 효율적으로 수정하는 일에 적극적이게 되고 결과적으로 깔끔한 코드를 유지할 수 있다.

 

반대로 테스트 코드가 없다면 당연하게도 리팩토링에 소극적일 수 밖에 없다. 멀쩡히 잘 돌아가는 코드를 건드렸다가 어떤 사고가 발생할지 예단하기 어렵기 때문에 일단은 코드가 마음에 들지 않더라도 넘어가기로 한다. 이렇듯 소스 퀄리티를 개선하는 일을 매번 미루고 결과적으로 끔찍한 레거시 코드로 남게 되는 것이다.

 

 

배포할 용기

테스트 코드는 배포할 용기를 준다. 새로운 기능을 추가 했는데, 이와 무관하게 돌아가야하는 기존 기능에 버그가 발생한 경험을 해본적이 있는가? 불행히도 나는 꽤 있었다. 물론 서로 다른 두 기능간 결합도를 낮추지 않은 코드 설계가 원인이겠지만 때로는 아주 작은 실수가 멀쩡히 돌아가던 기능을 망가뜨리기도 한다.

 

배포 이후 장애가 나는 것을 사전에 방지하려면 자동화된 단위 테스트를 돌려보면 된다. 촘촘하게 작성된 단위 테스트는 혹시 의도와 다르게 실수를 해서 다른 기능(혹은 방금 추가한 기능)을 망가뜨리지는 않았는지 검증해준다. CI/CD 파이프라인에 전체 테스트를 돌려보는 단계를 추가하여 이 과정을 자동화하면 더 효과적이다.

 

 

Test code saves us!

높은 테스트 커버리지가 장애 제로를 보장하는 것은 아니지만 장애 제로에 가까워질 수 있게 해준다. 이는 개발자가 더 적극적으로 코드를 개선할 수 있게 날개를 달아준다. 따라서 높은 퀄리티의 코드를 유지할 수 있게 해주며 빠르게 코드를 읽고 수정하고 배포할 수 있도록 돕는다. 이것이 결과적으로 생산성 향상으로 이어진다.

 

과장으로 들릴 수도 있겠지만(조금은 그럴지도 모르겠다) 그간 내가 체감한 테스트 코드의 위력은 이토록 위대하다. 그리고 만약 어딘가에서 새로운 프로젝트를 시작했는데 테스트 디렉터리가 텅 비어있다면 용기를 가지고 프로젝트 멤버들을 설득할 수 있길 바란다.

반응형