유닛 테스트 (Unit Test) 와 통합 테스트 (Integral Test)에 대해 알아보자
단위 테스트는 전체 코드 중 일부분만 테스트 하는 것을 뜻한다
전체 로직이 아닌 하나의 메소드를 각각 개별로 테스트한다면 이를 단위 테스트라고 할 수 있겠다.
@DisplayName("주문을 받아 주문 메뉴에 대한 할인전 결제 금액을 계산한다.")
@ValueSource(strings = {
"바비큐립,제로콜라",
"양송이수프,타파스,티본스테이크,아이스크림",
"티본스테이크,제로콜라,레드와인,샴페인",
"해산물파스타"
})
@ParameterizedTest
void orderPriceTest(String menuName) {
//given
OrderRepository orderRepository = new OrderRepository();
List<String> items = List.of(menuName.split(","));
Reservation reservation;
Map<MenuItem, Integer> menuItems = new HashMap<>();
int totalOrderPrice;
//when
items.forEach(menuItem -> menuItems.put(orderRepository.getMenuItemByName(menuItem), DEFAULT_QUANTITY));
reservation = new Reservation(menuItems, DEFAULT_DATE);
totalOrderPrice = menuItems.keySet().stream()
.mapToInt(MenuItem::getPrice)
.sum();
//then
assertThat(reservation.getTotalOrderPrice()).isEqualTo(totalOrderPrice * DEFAULT_QUANTITY);
}
위의 예시는 주문을 하고 결제 금액을 계산하는 지 테스트한다.
즉 Reservation 객체의 getTotalOrderPrice라는 메소드만 검사하는 것으로 단위 테스트라 할 수 있다.
이러한 단위 테스트의 특징은 다음과 같다.
매우 간단하고 명료해야한다.
유지보수에 유리하다.
코드 설계에 유리하다.
TDD 방식을 통한 단위 테스트 작성은 좋은 설계를 유도할 수 있다.
이는 코드 작성 전에 코드 설계에 대한 사고를 유도하기 때문이다.
또한 유닛 테스트를 작성하기 위해서는 모듈간의 의존성이 낮아야 하므로 결합도가 낮은 코드를 작성하게 돕는다.
💡 즉 단위 테스트는 매우 세분화된 코드의 정상 작동을 테스트한다.
어떠한 부분에 문제가 있고 고쳐야할 부분이 무엇인 지 파악하는데 도움을 준다.
어플리케이션의 각 요소들이 어떻게 상호작용하는 지를 검사하는 테스트이다.
전체적인 flow 관점으로 테스트하며 특히 Database와 앱이 잘 소통하고 있는 지, 외부 라이브러리와의 통신 등을 검사할 수 있다.
때때로 분리된 두 시스템이 정상적으로 통신하고 있는 지에 대해서도 테스트할 수 있으며
실제 통신 과정을 테스트하는 것이기 때문에, 단위 테스트보다 설정 과정과 구현 과정이 복잡할 수 있다.
또한 단위 테스트보다 더 많은 코드를 검사하기 때문에
세부적인 부분에서 오류가 발생하면 원인을 찾기 힘들다.
단위 테스트보다 유지보수 관점에서는 불리한 점이 있다.
스프링부트에서는 @SpringBootTest
를 통해 통합 테스트를 작성할 수 있다.