들어가며

테스트할 로직 중간에 데이터베이스가 끼어있는 경우가 많다. 이번 장에서는 단위 테스트와 통합 테스트 각각에서 데이터베이스를 어떻게 다루면 좋을지 학습해 보자.

 

단위 테스트에서의 데이터베이스

먼저 프로세스 외부 의존성의 유형을 짚고 넘어가자. 모든 프로세스 외부 의존성은 두 가지 범주로 나뉜다.

  • 관리 의존성 : 외부 의존성이지만 애플리케이션을 통해서만 접근할 수 있다. 데이터베이스가 대표적인 예이며, 외부 시스템은 보통 애플리케이션에서 제공하는 api를 통해서 데이터베이스에 간접 접근한다.
  • 비관리 의존성 : 애플리케이션과의 상호 작용을 외부에서 볼 수 있다. 예를 들어 SMTP 서버와 메시지 버스 등이 있다.

 

 

 

다시 본론으로 돌아오자. 이전 글인 코드 유형과 테스트의 관계 글에서 언급했듯이, 단위 테스트는 도메인 도델과 알고리즘을 대상으로 하고 통합 테스트는 컨트롤러를 대상으로 한다. 만약 도메인 모델과 알고리즘에 데이터베이스라는 외부 의존성이 존재한다면, 리팩터링을 먼저 한 다음에 단위 테스트를 진행해야 한다.

 

물론 스텁을 사용하여 해결할 수는 있다. 하지만 db는 보통 관리 의존성이기 때문에 테스트가 구현 세부 사항에 의존하게 된다. 테스트 용이성과 가독성 측면에서도 좋지 않으므로 이를 지양하자. 예외적으로 db 또는 db의 일부가 비관리 의존성인 경우가 있다. 그럴 때는 목이나 스텁을 사용해도 무방하다.

 

통합 테스트에서의 데이터베이스

이메일이나 푸시와 같은 비관리 의존성은 목으로 대체하고 상호작용을 검증한다. 하지만 관리 의존성을 목으로 대체하면 리팩터링 내성이 저하되고 회귀 방지도 떨어진다. 따라서 데이터베이스를 그대로 테스트하는 것이 바람직하다.

 

데이터베이스는 실제 운영 환경과 동일하게 하는 게 좋다. 인메모리 데이터베이스는 기능적으로 일관성이 없기 때문에 회귀 방지 측면에서 좋지 않다.

 

쓰기는 위험성이 높기 때문에 철저히 테스트해야 한다. 읽기는 보통 위험성이 없기 때문에 복잡하거나 중요한 작업만 테스트하고, 나머지는 무시해도 된다.

 

리포지토리 테스트는 유지비가 높고 회귀 방지가 떨어지기 때문에 이점이 별로 없다. 직접 테스트하기보다는 포괄적인 통합 테스트 스위트의 일부로 취급하라.

'테스트' 카테고리의 다른 글

목 사용 팁  (0) 2023.09.18
코드 유형과 테스트의 관계  (0) 2023.09.17
단위 테스트의 세 가지 스타일  (0) 2023.09.17
테스트 대역(Test Double)이란?  (0) 2023.09.17
좋은 단위 테스트의 4대 요소  (0) 2023.09.17

단위 테스트

단위 테스트란 1) 작은 코드 조각을 검증하고, 2) 빠르게 수행하고, 3) 격리된 방식으로 처리하는 자동화된 테스트다. 여기서 작은 코드 조각과 격리된 방식을 어떻게 정의하느냐에 따라 런던파와 고전파로 나뉜다. 

 

가령 `친구가 공을 던진다` 라는 행위를 각 분파의 방식으로 테스트 해보겠다. 런던파는 단일 클래스만을 검증한다. 따라서 공을 목으로 처리하고 친구라는 클래스만 검증한다. 반면, 고전파는 단일 동작을 검증하기 때문에, 친구와 공 모두 실제 클래스를 사용하여 행위를 검증한다. 

 

  격리 주체 단위의 크기 테스트 대역 사용 대상
런던파 단위 단일 클래스 불변 의존성 외 모든 의존성
고전파 단위 테스트 단일 클래스 또는 클래스 세트 공유 의존성

 

위 표에 나와 있듯이 격리 방식에도 차이가 있다. 런던파의 격리 주체는 단일 클래스이기 때문에 친구와 공이 서로 격리되어 있다. 하지만 고전파는 클래스가 아니라 테스트 단위로 격리한다. 성공과 실패를 각각 테스트 한다고 하면, 두 테스트는 서로 간섭하지 말아야 한다는 의미이다. 그러기 위해서는 데이터베이스나 싱글톤 같은 요소가 서로 공유되지 말아야 한다.

 

필자는 고전파 방식이 리팩터링 내성과 테스트 유효성이 높다고 판단하였기 때문에 해당 분파를 지지한다.

 

통합 테스트

통합 테스트는 단위 테스트 정의 중 하나를 충족하지 않는 테스트다. 데이터베이스와 같은 공유 의존성에 접근하거나, 둘 이상의 동작 단위를 테스트하는 것이 이에 해당된다.

 

엔드 투 엔드 테스트

엔드 투 엔드 테스트는 통합 테스트의 일부로, 일반적으로 외부 의존성을 더 많이 포함한다. 보통 통합 테스트는 프로세스 외부 의존성을 한두 개만 갖고 동작한다. 반면에 엔드 투 엔드 테스트는 프로세스 외부 의존성을 전부 또는 대다수 갖고 작동한다. 즉, 모든 외부 애플리케이션을 포함해 시스템을 최종 사용자의 관점에서 검증하는 것을 말한다. 동의어로 UI 테스트, GUI 테스트, 기능 테스트가 있다.

+ Recent posts