본문 바로가기

Backend/질문 시리즈

[질문-시리즈] 테스트 코드 작성에 대한 피로도가 심해요

[질문 시리즈]는 주변 개발자 분들께 제가 생각하는 내용을 질문 후 답변들을 정리한 내용입니다.
해당 포스팅은 질문에 대한 정답을 명확히 하는 것이 목표가 아닙니다.
프로젝트를 바라보는 관점에 따라 의견이 다양해질 수 있고, 이 글 또한 여러 관점 중 하나일 뿐이라 생각합니다. :D

질문

요구사항을 왜 바꿔! 돌려줘!

프로젝트를 진행하다 보면 기존 코드를  기반으로 테스트 코드를 작성해야 하는 경우가 있고, 처음부터 테스트 코드 기반 개발을 진행할 수도 있습니다.

저 같은 경우 틀이 정해지지 않은 후자의 방법으로 프로젝트를 시작하였습니다.

 

처음 테스트 코드를 작성할 때는 어떤 범주의 테스트 코드를 작성할지 상의 후 개발을 진행했습니다.

  • 어떤 값을 넘겨주는지
  • 테스트 대상 메서드 내부에서 특정 메서드를 호출되었는지
  • 테스트 대상 메서드 내부에서 특정 메서드에게 특정 값이 넘겨졌는지
  • 테스트 대상 메서드가 특정 결과를 반환했는지
  • 특정 상황에 예외처리가 정상 호출되었는지

나름 상세한 테스트라 생각하였고, 해당 범주의 테스트 코드를 통해 초기 개발을 유도할 수 있었습니다.

하지만 개발 중반부터 변경사항이 발생 후 여태 작성한 테스트 코드를 딱 보니 바로 이 생각이 들었습니다.

아 큰일 났다. 이거 다 바꿔야 하네

인터페이스로 분리하고, 패키지의 의존 방향을 고려하는 등 SOLID 원칙을 지키고,  인스턴스 생성을 직접 호출하지 않는 등 TDA원칙을 고려하여 요구사항의 변경에 대한 이펙트를 최소화하기 위해 많은 노력을 코드에 적용했습니다.

그 결과 작성한 코드에는 변경할 부분이 쉽게 확인되고, 변경 범위 또한 크지 않음을 확인했습니다.

참 아이러니하게도 작성한 코드에 대한 변경이 크지 않았지만, 테스트 코드는 그렇지 않았습니다.

로직의 최종 결과는 동일했지만, 호출할 메서드와 인자가 변경되었고 더 이상 호출할 필요가 없어 제거 대상으로 변한 메서드가 생겼습니다.

결국 제가 주도한 테스트 코드는 이 변경을 통과하기 위해 테스트했던 내용을 제거하고, 새로 호출하게 된 메서드와 인자에 대해 처음부터 다시 테스트 코드를 작성해야 했습니다.

 

해당 경우가 한 번으로 끝나면 좋았겠지만 개발이 지속될수록 비슷한 경우가 발생하고, 테스트 코드가 시멘트 덩어리 같이 느껴지다 보니 고민이 생겼습니다.

내가 하고 있는 방법이 정말 올바른 TDD인가?

답변

원칙은 원칙일 뿐. 결과 중점의 테스트를 고려해봅시다.

우선 인자를 넘기고, 메서드가 호출되는지 등 상호작용을 중점으로 테스트하는 방법을 구현 테스트라고 정의하겠습니다.

객체지향적 관점에서 테스트 방법은 틀리지 않았고, 당연히 변경이 발생하면 테스트 코드가 변경되야하는 것이 맞습니다.

그래야 동작 코드 중 어느 곳이 변경됐는지 알 수 있고, 통합 테스트 과정에서는 다른 기능의 변경으로 인해 실패할 경우를 차단하여

다양한 요구사항을 누락 없이 동작 코드에 녹여낼 수 있기 때문입니다.

하지만 원칙에 가까운 방법이기도 하고, 당연히 질문의 내용처럼 피로감이 생깁니다.

이를 회피하려면 A를 요청하면 B가 나와야 한다! 를 반영한 결과 중점 테스트를 고려해볼 수 있습니다.

  • A 인자를 넘겼을 때 테스트 대상 메서드가 특정 결과를 반환했는지
  • B 인자를 넘겼을 때 테스트 대상 메서드가 예외처리가 발생하는지

테스트 범주를 좁혀 핵심적인 테스트를 진행하면, 변경에 대한 고민을 최소화할 수 있습니다.

답변을 받은 후 정리된 생각

처음 TDD를 적용하고자 했을 때 목표 사항은 코드의 형상관리였습니다.

특정 코드가 변경됨으로 다른 코드의 결과에 영향이 생길 수 있다 생각하여 형상이 올바르게 변하지 않으면 문제가 발생하는 게 맞아!

라는 생각으로 적용했던 게 어느새 잊어버렸습니다.

당연히 목표하는 요구사항이 변경되었으니 형상이 변경되는 것이고, 당연하게 형상이 바뀌었으니 테스트 코드 자체가 변경되어야 하는 것이 맞다고 생각합니다.