글 작성자: 개발섭

이번 인턴을 진행하면서 테스트 코드를 작성해볼일이 있었고, 그것에 대해서 느낀점을 작성하려고 한다. 테스트 코드를 왜 써야하며, 그리고 테스트 코드에 대한 생각을 나눠보겠다.

테스트 코드를 왜 작성해야하나...?

테스트 코드를 작성하기 전에는 코드 작성시 굳이 테스트 코드가 필수적으로 필요한지에 대한 생각을 많이 했었다. 인턴 이전까지만 해도 모든 테스트를 수작업을 통해 작동시켜보기도 했었다.

 

당시에는 이런 방법이 안정적으로 테스트를 할 수 있는데 큰 도움을 준다고 생각했기 때문에, 테스트 코드의 당위성에 대해서 크게 큰 신경을 쓰지 못했다. PostMan으로 테스트 하면 되는데 왜...? 굳이..? 그리고 그렇다고 해서 확실히 된다고 보장을 할 수는 있나..?

특히, 이 포스트 맨으로 테스트를 구성하는 경우 특히 서비스 플로우대로 테스트를 해볼 수 있으며, 테스트시 문제를 바로 캐치할수도 있다는 점이 가장 큰 장점이했다.

 

대충 이런식으로 각 프로젝트별로 따로 관리했었다.  
 각 상황별로 플로우를 다 체크해봐야했는데... 점점 늘어날 수록 테스트가 빡세진다.

물론 그만큼 한번의 서비스 플로우(회원가입후 로그인, 서비스 사용처럼 여러가지 행동 양식들)가 증가하면 증가할 수록 여러가지의 경우에 대해서 모두 따져줘야하는 점이 늘어난다는 것이 벅차긴했으나, 소규모 서비스의 경우는 테스트를 그만큼 하지 않아도 대부분은 동작했기때문에(버그도 산재해있었겠지만...) 대부분 일단 기능을 빠르게 구현하는 것이 우선이었다.

기능을 구현이야 빠르지만...

아까 말했듯이 기능 구현자체는 어떻게든 구현할 수 있다. 결국 내가 여기저기서 삽질과 들이박음을 통해서 겨우겨우 기능 구현을 하게되면, 그 기능에 대해서또 수기로 postman을 통해서 다시 테스트를 해줘야한다. 그러다 보면, 점점 테스트가 버거워지는 경우가 생긴다.

내가 혹은 팀에 혹은 회사 자체에서 필요한 기능은 점점 더 많이 구현해야하며, 테스트 해야할 양은 또 그만큼 늘어나며... 아이고.. 점점 기능 구현보다는 이게 더 잘 돌아가는가처럼 테스트에 홍수에 빠져서 죽거나 혹은 아니면 되겠거니.. 그때 대응하자처럼 자포자기하는 심정일 것이다.

 

위의 문제는 근성(악으로 깡으로 버텨라..)으로 어떻게 처리하면 된다지만, 이렇게 테스트했을때 가장 큰 단점은 코드를 고쳤을때이다. 사람이 기능 수정, 리펙토링, 로직변경과 같은 세부적인 내용을 고쳤거나 짜잘한 개선사항을 한 뒤에, 바로 테스트하는 경우는 있긴하겠지만 빼먹기 쉽다. (맘처럼 잘 안된다. 커밋 하나당 모든 테스트를 다해야한다고 생각해보라.)

고치면 고칠수록 문제는 심각해진다.

그리고 커밋 한 두개쯤 넘기면서 진행한 테스트들은 항상 그 한 두번 빼먹은 곳에서 항상 에러가 난다. FE와의 개발 도중 뜬금없이 발생하는 오류라던가 잘되던게 어디서부턴가 잘 안된다던가.. 오류가 없던 장소에서 오류가 난다던지. 별의 별 상황이 많이 생긴다.

그러면 도대체 무슨 코드를 수정했어서 이런 오류가 생긴건지 다시 차근차근 되돌아가봐야하는데, 이게 상당히 귀찮다. 그만큼 생산성이 떨어지는 행동이기도 하다. 한번에 쭉 잘되면 잘될것이지... 이전에 고친것들을 차분하게 확인해보는 과정을 확인하는 것 자체가 한일을 또 반복하는 행동처럼 느껴진다.

 

결국 이런 반복행동을 생성하는 등의 리스크를 가지는 코드 수정을 굳이 해야할까라는 마음이 생기고, 하지말자라는 결론이 나기 시작하면 그때부터는 되돌릴수도 없는 상태가 된다. 이제 그때부터는 산발적인 수정을 계속 반복해야하는 상태가 되는것이다.

결국에는 중요한 배포,발표와 같은 일이 있을때 문제가 있어보이지만, 코드를 수정을 했다가는 아예 실행이 안되거나, 멈추는 상황이 생길수도 있으니 그냥 아예 코드를 건드릴수 없는 상황까지 만들어진다.

테스트 코드

테스트 코드는 위에서 말하는 코드를 고쳤을때의 리스크를 훨씬 많이 줄여준다. 테스트 코드를 막상 작성하기 전에는 엄청 귀찮은 작업이긴하다. 각 로직별로 이것들이 문제가 있는지 그리고 이게 A → B가 맞게 나오는지? 그리고 A→B가 안나오면, 왜 안나오는지를 어쨌든 테스트코드를 짜면서 문제점을 한번은 체크하고 넘어가게 된다.

 

그리고 결정적으로 이런 테스트 코드를 작성하면 수정이 편해진다. 만약 수정을 했는데 문제가 발생했다? 그러면 테스트를 확인해보면 된다. 어떤 부분에서 문제가 생겼을지 확인도 훨씬 빨라지며, 그리고 애초에 테스트 코드가 있어서, Postman과 같은 툴 자체를 쓸 이유도 없다. 내부 테스트를 돌려서 문제가 발생하는 지 먼저 체크를 해서 수정에 문제가 있는지만 확인하면 된다.

솔직히, 테스트 코드가 필요하다 필요하다 말은 많이 한다. 왜 필요하고 도대체 쓰면 뭐가 좋은지를 알수가 없었다.

 

그런데, 인턴시에 실제로 써보니까 기능 추가, 수정시에 정말 큰 도움이 되기시작한다. 점점 늘어나는 코드량, 점점 복잡해지는 로직, 점점 많아지는 예외들을 수작업으로 하는 것은 어려운 일이고 테스트를 하기 시작하면 오류가 없을것이다. 버그가 없을 가능성이 크다라고 코드를 작성한 사람이 생각하기 좋다. 왜냐면, 실제로 논리적 오류를 테스트를 통해서 많이 해결해냈으니까.

자신감과 더불어 너무 길고 수없이 보기 어렵게 불편하게 작성되있는 코드들을 고칠수 있을거라고 생각할 수 있으며, 결국 가독성 좋은 코드, 간결한 논리로 작성된 코드를 구현할 수 있게 만들 수 있다. 코드를 잘 작성하는 것이 큰 도움을 받을 수 있기 때문에 크게 도움을 받을 수 있다고 적어도 짤막하게 해본 내가 도움을 얻은 내 의견이긴하다.

P. S. 테스트 코드를 환상적으로 더 쓰는 법

테스트 코드를 조금 더 효용성 있게 쓸 수 있는 방법에 대해서 잠깐 이야기 해보겠다. 테스트 코드를 작성할때 가장 머리 아픈부분은 이렇게 테스트 코드를 짜는 것이 맞는가에 관한 부분이다.

 

특히, 그것이 어렵다고 느껴지는 부분은 A → B 가 올바르게 나오는게 할수는 있겠으나, 이렇게 하는게 맞는지...? 라는 부분에서는 정답을 내릴만한 근거가 상당히 부족한 면이 있다. 왜냐하면, A→B를 만드는 과정은 사람마다 정말 제각각이기때문이다. 여러 사람들의 테스트 코드들이 각자가 설정한 기준이 없기도하며, 이 작성하고 있는 테스트 코드가 맞는지에 대한 기준이 내려져있지 않은 것이 이러한 골치거리를 마음 한켠에 생성하는 원인 중 하나라고 본다.

코드 커버리지는 기준점이 있어서 테스트 코드가 쉬워진다.

그렇다면 우리는 이 기준에 대해서 무엇인가 도움을 받을 수 있는 것이 있다, 그것은 바로 코드 커버리지 도구인데, 내가 작성한 코드들에 대해서 어디까지 테스트 코드가 검사하는지를 알려주는 도구로써,

if문과 같은 분기에 대해서도 내 테스트 코드가 검사하는 지를 파악할 수 있는 지표중 하나가 된다. 끝도 없이 작성했었던, 수없이 많은 줄의 내 코드가 얼만큼 테스트 코드로 검사받는지를 알 수 있어서, 내가 테스트 코드를 작성하는 부분이 어떤 부분인지를 알려준다.

 

즉, 이런 기준을 수치적으로 도움을 받을수 있는 툴이 Code Coverage툴이다.

 

테스트 코드를 통해서 검사 받지 않은 줄이 있는지, 그리고 그 테스트 코드를 통해서 검사받지 않은 분기가 있는지를 확인해서, 테스트 코드를 여러가지 분기, 그리고 특정 상황을 체크해서 구현해낼 수 있으며, 내가 작성한 코드들의 문제점을 수치적으로 확인해볼 수 있는 좋은 툴이다.

여러가지 언어에 대해서 테스트 툴과 이 코드 커버리지 툴을 사용하게되면 큰 도움을 받을 수 있을것이다.