반응형
통합 테스트
런던파의 통합 테스트 : 실제 협력자 객체를 사용하는 모든 테스트를 통합 테스트이다. 고전파는 런던파 입장에서 모두 통합 테스트이다.
고전파의 통합 테스트 : 공유 의존성 접근하는 테스트 또는 둘 이상의 동작 단위 검증할 때 통합 테스트이다.
단위 테스트의 정의
- 작은 코드 조각을 검증
- 빠르게 수행 가능
- 격리된 방식으로 처리 가능
→ 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트
좋은 테스트의 규칙(FIRST)
- Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
- Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
- Repeatable: 어느 환경에서도 반복 가능해야 한다.
- Self-Validating: 테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.
- Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.
테스트를 바라보는 관점(고전파 VS 런던파)
격리 수준을 어떻게 하느냐에 따라 크게 2가지 관점으로 나뉨
- 고전파
- 고전주의적 접근법
- 테스트 주도 개발(켄트 백, 테스트 주도 개발)
- 의존성과 테스트 대상 시스템 모두 준비해야 함
- 런던파
- 목 추종자
- 런던 스타일
- 테스트 대상 시스템(SUT, System Under Test)을 협력자(Collaborator)에게서 격리
- 클래스 간의 의존성을 줄일 수 있음
- SUT 에 보다 집중 가능
런던파의 경우, 테스트 대상 시스템의 의존성을 테스트 대역으로 대체 → 테스트 대상 시스템만 검증하는데 집중 가능
고전파의 예
@SpringBootTest
@Transactional
class OrderServiceTest {
@Autowired
EntityManager em;
@Autowired
OrderService orderService;
@Autowired
OrderRepository orderRepository;
@Test
public void 상품주문(){
//given
Member member = createMember();
Book book = createBook("시골 JPA", 10000, 10);
//when
int orderCount = 2;
Long orderId = orderService.order(member.getId(), book.getId(), orderCount);
//then
Order getOrder = orderRepository.findOne(orderId);
// 상품 주문시 상태는 ORDER
assertThat(getOrder.getStatus()).isEqualTo(OrderStatus.ORDER);
// 주문한 상품 종류 수는 정확해야 한다.
assertThat(getOrder.getOrderItems().size()).isEqualTo(1);
// 주문 가격은 가격 * 수량이다.
assertThat(getOrder.getTotalPrice()).isEqualTo(10000*orderCount);
// 주문 수량만큼 재고가 줄어야 한다.
assertThat(book.getStockQuantity()).isEqualTo(8);
}
여기서 SUT는 상품 주문(order)이고, 협력자는 book 과 member 이다. 대표적인 고전파 방법으로 테스트를 한 예이다.
런던파의 예
MemberService의 경우 구현체는 없고, 인터페이스만 존재한다.
@DataJpaTest
@ExtendWith(MockitoExtension.class)
@Slf4j
class StudyServiceTest {
@Mock MemberService memberService; // 선언적으로 Mock 만드는 방법
@Mock StudyRepository studyRepository;
@Test
void createNewStudy() {
// Given
StudyService studyService = new StudyService(memberService, studyRepository);
assertNotNull(studyService);
// stub 세팅
Member member = new Member();
member.setId(1L);
member.setEmail("asdf@email.com");
Study study = new Study(10, "테스트");
given(memberService.findById(1L)).willReturn(Optional.of(member));
given(studyRepository.save(study)).willReturn(study);
// When
studyService.createNewStudy(1L, study);
// Then
assertNotNull(study.getOwnerId());
assertEquals(member.getId(), study.getOwnerId());
then(memberService).should(times(1)).notify(study);
then(memberService).shouldHaveNoInteractions();
}
}
Mockito 라이브러리를 사용하여 런던파 스타일로 테스트를 구현한 것
격리 주체 단위 크기 테스트 대역 사용 대상
격리 주체 | 단위 크기 | 테스트 대역 사용 대상 | |
런던파 | 단위 | 단일 클래스 | 불변 의존성 외의 모든 의존성 |
고전파 | 단위 테스트 | 단일 클래스 또는 클래스 세트 | 공유 의존성 |
통합 테스트
- 런던파의 통합 테스트 : 실제 협력자 객체를 사용하는 모든 테스트를 통합 테스트이다. 고전파는 런던파 입장에서 모두 통합 테스트이다.
- 고전파의 통합 테스트 : 공유 의존성 접근하는 테스트 또는 둘 이상의 동작 단위 검증할 때 통합 테스트이다.
엔드 투 엔드 테스트(end-to-end test)
엔드 투 엔드 테스트는 공유 의존성뿐만 아니라 조직 내 다른 팀이 개발한 코드 등과 통합해 작동하는 테스트다. 일반 통합 테스트보다 더 많은 의존성이 있다. UI(User Interface), GUI(Graphic User Interface) 테스트라고도 할 수 있다.
엔드 투 엔드 테스트 작성에 가장 많은 비용이 발생하기 때문에 모든 단위 테스트, 통합 테스트 통과한 후 후반에 작성, 실행하는 것이 좋다.
참조
- 단위테스트(블라디미르 크리코프)
반응형
'테스트코드 > 개요' 카테고리의 다른 글
6. 단위 테스트 스타일 (0) | 2024.03.25 |
---|---|
5. 목과 테스트의 취약성 (0) | 2024.03.25 |
4. 좋은 단위 테스트의 4대 요소 (2) | 2024.03.25 |
3. 단위 테스트 구조 (0) | 2024.03.25 |
1. 단위 테스트의 목표 (1) | 2024.03.25 |