테스트를 작성해야 하는 이유

왜 우리는 시간을 들여 테스트를 작성해야 하는가 | 2025-01-15

이전에 티스토리에서 테스트를 작성해야 하는 이유에 대해 생각을 작성했어요.
이 글은 해당 게시글을 다시 가공하고 최근 생각을 추가했어요.


테스트 코드를 그래서 왜 작성해요?


종종 테스트 코드를 작성하는 이유에 대한 질문을 받아요.
전에는 단순히 ‘내 코드가 안전하다는 것을 보장’한다고 답변을 했어요.



테스트 코드를 작성하지 않는다면 어떤 일이 생겨요?

테스트 코드를 작성하지 않는다고 해서 문제가 발생하는 것은 아니에요.
정말 아무 문제 없이 돌아가요.

테스트 코드가 없다면 위와 같은 상황이 보통 발생해요.
잘 개발해서 배포를 완료했지만 사용자를 통해 버그가 발견될 수 있죠.

테스트 코드를 작성하게 되면 위와 같이 테스트 코드를 통해 어느 정도 막을 수 있어요.
그러나 테스트 코드가 모든 케이스를 커버할 수 없기 때문에 결과론적으로 사용자를 통해 버그가 발견될 수 있는 것은 마찬가지에요.



그럼 더욱 테스트 코드를 작성할 필요가 없는 것이 아닌가요?

필요성을 느끼지 못한다면 굳이 작성할 필요는 없다고 생각해요.
그러나 저는 내키지 않지만 열심히 테스트 코드를 작성해두니 많은 좋은 점을 겪었어요.


1. 테스트 코드 자체가 설명서

먼저 테스트 코드 자체가 코드를 설명해줘요.
한참 이전에 개발했고 바빠서 문서화를 제대로 하지 못한 상황이에요(핑계).
이럴 때는 테스트 코드 자체가 해당 기능을 설명해줬어요.

func test_어떤_버튼을_눌렀을때_어떤_동작이_발생한다() {
  /* 생략 */
}

위와 같이 테스트 케이스를 작성하니 테스트 코드만 봐도 이해가 가는 부분이 많았어요.
굳이 비즈니스 로직을 전부 파헤쳐 볼 필요가 없어요.


2. 이 코드 바꿔도 괜찮나요?

개발은 하드웨어가 아닌 소프트웨어를 다루는 일이에요.
즉, 변경이 가능해야 하죠.
해당 기능을 참조하는 코드가 적다면 변경이 정말 수월해요.

위 이미지에서 MapRepository가 변경된다고 가정할게요.
MapRepository에 있는 기능이 변경되었을 때 저희는 MapUseCase 그리고 MapPresentation만 정상적으로 동작하는 지 확인하면 끝이에요.

그러나 여러 곳에서 해당 기능을 호출하고 있다면 어떻게 될까요?

MapRepository를 참조하고 있는 코드가 많다면 어떻게 될까요?
기능이 변경되면 DriverUseCase, MapUseCase 그리고 FoodUseCase도 기능이 변경될 수 있어요.
또한 Presentation들도 예상치 못한 동작을 할 수 있어요.

그 기능을 변경하고 그 기능과 연관된 모든 케이스를 다 확인해야 하나요?
테스트를 작성하지 않았다면 모든 케이스를 다 확인해야 해요.
결국에는 리소스가 많이 들고 이는 곧 비용으로 연결이 돼요.

만약 테스트가 견고하다면 이러한 걱정이 덜어져요.
기능이 변경되었을 때 동작이 다르다면 테스트가 실패하기 때문이에요.
또한 테스트 코드는 보통 기능을 개발하거나 수정할 때 작성을 해요.
이 말은 해당 기능의 스펙을 가장 잘 알고 있는 상황이라는 얘기에요.

테스트 코드를 작성하는 시기가 해당 기능을 잘 알고 있는 상황이라 테스트 코드 작성에 많은 리소스가 들지 않아요.
반대로 테스트 코드를 작성하지 않고 기능을 변경했다면 다른 기능에 대한 스펙을 하나하나 정상적으로 동작하는지 확인해야 해요.
스펙을 다시 이해하는데 드는 비용도 추가적으로 들어요.

즉, 테스트 코드를 작성하는 것이 추후 있을 변경에 대한 안전성을 제공해주는 것이며 이는 비용 감소와 연관이 되어있다 정도로 생각해도 좋을 것 같아요.


테스트 코드만 작성하면 되나요?

여러 방법론이 있지만 저는 주로 BDD를 활용하고 있어요.
테스트 코드 또한 유지 보수가 이루어져야 해요.

앱을 개발할 때 빌드를 하여 정상 동작을 하는지 확인을 하는데 테스트 코드는 매번 테스트를 돌리기가 어려워요.
또한 특정 코드가 변경이 되어 테스트가 깨져도 Xcode같은 경우는 컴파일 에러가 나는 것이 아닌 정상적으로 빌드가 되어요.
따라서 어느정도 강제적으로 테스트를 돌리기 위한 장치가 필요해요.

먼저, CI(Continuous Integration, 지속적 통합)를 통해 PR을 올렸을 때 테스트를 진행시켜 확인하는 방식이 있어요.
저는 주로 CI를 통해 배포가 나가기 전에 테스트를 진행시키고 있어요.

다른 방법으로는 pre-commit을 활용하는 방법이 있어요.
git에 커밋이나 푸시를 하기 전에 테스트를 진행시킬 수 있어요.
저는 주로 pre-push를 통해 푸시를 하기 전에 로컬에서 테스트를 진행시키도록 반강제하고 있어요.


결국 테스트 코드도 코드에요.
잘 작성하고 유지 보수도 잘한다면 비용을 많이 줄일 수 있을 거에요.

물론 테스트 코드의 중요성을 몰라 이를 설득해야 할 수도 있어요.
이런 상황이 참 어려운 것 같아요.
테스트 코드를 작성함으로 비용이 얼마나 줄일 수 있는지 정량적으로 표현하기 어려워요.
마치 문서화 같은 느낌이에요.
당장 내가 아닌(내가 될 수 있지만) 나중을 위한 일이니깐요.