개발 공부 기록하기/20. 일반

[공유] 유용한 테스트 케이스를 위한 개발자의 자세

lannstark 2020. 10. 7. 09:11

https://meetup.toast.com/posts/246

 

유용한 테스트 케이스를 위한 개발자의 자세 : TOAST Meetup

각종 커뮤니티에 주기적으로 등장하는 "private 메서드를 테스트하려면 어떻게 하나요?" 혹은 "private 메서드를 테스트해야 하나요?"와 같은 질문을 보면서 언젠가는 관련해서 정리해봐야겠다고 생

meetup.toast.com

위 글을 읽으며, 다시 한 번 생각해볼만한 문구를 나름대로 정리!

좋은 글 감사합니다 🙇

 

무조건 TC를 작성한다고 도움이 되는 것이 아니다. TC는 적을 수록 좋다. 최소의 TC로 최대의 효과를 낼수록, 즉 효율이 높을수록 테스트의 가치는 더 뚜렷해진다. 반대의 경우라면 수많은 TC가 프로젝트의 민첩성을 떨어트리고 사사건건 발목을 잡을 것이다. 이런 상태가 되면 테스트에 반감을 갖게 될 수밖에 없다.

 

불필요한 TC가 많을수록 실제로 도움이 되고 꼭 필요한 TC들의 가치가 떨어지게 되고 프로젝트의 TC에 대한 신뢰도는 바닥을 친다. TC는 신뢰를 잃는 순간 legacy 보다 못한 프로젝트의 걸림돌이 된다. 이제 와서 TC를 작성하는 것은 그만 만들 수도 없고, 또 지울 수도 없지만, 도움은 전혀 되지 않는.. 혹은 도움이 된다고 착각하는 그런 TC가 된다.

 

오래된 톱니바퀴는 더 가볍거나 더 빠르고 안정성이 좋은 톱니바퀴로 교체될 수 있다. 이때 톱니바퀴가 속한 기관은 해당 톱니바퀴에 맞물려 돌아갈 수 있게 톱니의 모양만 알고 있으면 되지 이게 무슨 재질이고 어떤 색인지 혹은 어떤 상표인지 따위는 몰라도 된다. 그냥 무엇이든 톱니 모양만 맞는다면 그것으로 충족하는 것이다. 그렇기 때문에 새로운 톱니바퀴를 돌리기 전에 테스트해볼 것은 그 톱니바퀴와 함께 돌아갈 다른 톱니와 제대로 맞물리는지만 확인하는 것으로 충분하다.

  • 개인적인 생각이지만, 복잡한 비즈니스 로직을 가진 컴포넌트들은 맞물리는지 외에 '어떤 재질이고 어떤 색인지'도 테스트 해야할 때가 있다. 밖에서 톱니바퀴가 보인다면 색깔도 중요하지 않겠는가. 예를 들어, A case에서는 금액이 100원으로 나오고, B case에서는 금액이 200원으로 나오고, .... J case에서는 금액이 5000원으로 나와야 한다면 다른 누군가의 작업으로 B case에서 금액이 300원으로 나오게 바뀌지 않았는지 확인해줄 테스트가 필요하다.
  • 또한 이러한 테스트는 커뮤니케이션에서도 잘 활용될 수 있는데, 회의 중에 '앗 우리 E case에서는 금액 어떻게 나오고 있어요?'라고 질문이 나오면 테스트 코드를 보고 바로 대답해줄 수 있기 때문이다. 만약 이러한 테스트 코드가 없다면 '잠시만요 확인해볼게요' 라고 말하고 10분을 넘게 해당 로직을 local에서 돌려봐야 할지도 모른다.
  • 물론 위와 같은 테스트를 작성할때 특정 로직(ex. method 1개)만을 테스트 하는 것이 아니라 DB에 표현된 table 들을 적절히 추상화한 비즈니스 로직 component들로 역할을 적절히 분담하고 해당 component에 대한 테스트를 작성하는 것이 바람직하다고 생각한다.
  • 생각해보면 결국 "A case에서는 금액이 100원으로 나오고, B case에서는 금액이 200원으로 나오고, .... J case에서는 금액이 5000원으로 나와야"하는 것은 해당 business component에 대한 책임이 되며, 그 책임을 테스트 하는 것이 된다.

 

TC는 대상 모듈이 무엇이든 시스템에 맞물려 정상적으로 돌아갈 수 있는지만 확인해야 한다. TC는 바뀔 수 있는 구체적인 모듈이 아닌 바뀌지 않을 모듈의 책임을 테스트해야 한다. 모듈이 적절해 책임을 수행하도록 메시지를 받을 수 있는 외부 인터페이스가 자주 바뀐다면 그것은 무언가 잘못 걸계되었다는 신호다.

 

현재를 위해 작성되는 TC는 개발하고 있는 코드의 테스트를 자동화한다. 이런 TC가 쌓여감에 따라 이후 작성된 코드가 side effect로 이전 코드를 망치는 것을 예방해준다. TDD가 애플리케이션의 구조적인 설계를 직접적으로 도와주지는 않지만 이미 짜여진 협력 구조 안에서 각 모듈의 역할과 책임에 필요한 인터페이스를 효과적으로 설계하는 것에는 도움이 된다. 그리고 이 과정에서 내부와 외부가 확실히 구분되고 정교하게 다듬어진다. TC를 먼저 작성한다는 것은 모듈을 사용하는 입장에서 개발을 시작하는 것이기 때문이다.

 

미래를 위한 TC는 모듈의 역할과 책임을 설명할 뿐 아니라 구체적인 사용 방법까지 제시하는 훌륭한 문서가 되어야 한다. 그래서 description을 읽는 것만으로 TC가 무엇이 어떻게 되는 것을 기대하는지 알 수 있도록 작성해야 한다.

 

결국, TDD 사이클을 이용하든 하지 않든 TC를 작성하면서 소비한 시간에 대한 충분한 효율을 얻으려면 현재를 위해 TC를 작성하되 개발이 진행되면서 미래를 위한 TC들로 바뀌어야 한다. 요지는 개발을 진행하면 필요 없는 TC들은 지우거나 더 나은 테스트로 개선되어야 한다는 것이다.

 

프로젝트에 TDD나 테스트 자동화를 도입했다면 모듈과 마찬가지로 TC도 지속적으로 개선하고 리팩토링해야 한다. 모듈들이 외부 인터페이스를 유지한 채 내부 코드들을 더 빠르고 더 간결하고 더 이해 가능하게 개선할 수 있는 이유는 TC들이 뒤에서 받쳐주고 있기 때문이다. 모듈과 마찬가지로 처음부터 완벽한 코드가 나올 수 없기 때문에 TC 역시 더 빠르고 더 간결하고 더 이해 가능하게 개선되어야 한다. TC는 모듈을 테스트하는 모듈이다. 적어도 모듈 정도 만큼 중요하게 생각해야 한다. TC를 만들었다고 해서 언젠간 도움이 되는 게 아니다. 오히려 아무짝에도 쓸모 없고 방해만 될 수 있다. 도움이 되는 TC를 만들도록 계속 고민하고 더 나은 테스트 방법에 대해 생각해야 한다.

 

내부 구현은 공개된 인터페이스를 통해서만 테스트해야하며, 내부 구현이 어디까지 테스트 되고 있는지 파악하기 힘들때 사용하라고 만든 지표가 coverage이다. 개발자들이 TC를 잘 작성하고 있는지 감시하려고 만든 수단이 아니다.