2022년 4월 11일 TIL

yshjft·2022년 4월 11일
0

데브코스 TIL

목록 보기
16/45
post-custom-banner

테스팅 레벨

  • Exploratory

  • end-to-end
    UI까지 포함한 테스트

  • component
    서비스 전체를 테스트

  • integration
    외부 서비스(DB, AWS 등)와의 연동 테스트

  • unit
    가장 작은 단위의 테스트

단위 테스트

  • 백엔드 엔지니어들이 가장 많이 접할 테스트
  • 빠르며 특정 부분을 고립시켜 테스트한다.
  • 지속적인 변경 상황에서 안정성을 확보할 수 있다.
  • 기능 명세로서의 역할
  • GIVEN: 전제 조건
  • WHEN: 행위 호출
  • THEN: 결과 확인
  • SUT: System Under Test, 테스트 대상, class

테스트 더블

테스트 대상 코드와 상호작용하는 객체(Mock 객체, stub)

통합 테스트

  • 다른 의존 관계와 연동이 잘 되는지를 확인

JUnit

  • 독립적인 테스트가 가능하도록 한다.
  • 테스트 코드를 쉽게 실행할 수 있게 한다.
  • assert로 테스트 케이스의 수행 결과를 판별하게 해준다.

JUnit5

JUnit4의 (IDE 등에 대한)확장성 부족으로 등장하였다.

JUnit Platform

테스팅 프레임워크를 런칭하기 위한 근간을 제공

JUnit Jupiter

TestEngine의 실제 구현체로서 Jupiter API를 사용해서 테스트 코드를 작성할 수 있게 한다.

JUnit Vintage

JUnit 4버전으로 작성한 테스트 코드를 실행할 수 있도록 한다.

테스트 코드 작성

Stub

  • 상태 검증(stub)
    메소드가 수행된 후, 객체의 상태를 확인하여 올바르게 동작했는지 확인하는 검증법

Mock & Mockito 사용

  • 행위 검증(Mock)
    특정 동작을 수행하는지 확인하는 검증법

inorder의 경우 메소드 호출 순서가 다르면 테스트를 통과할 수 없다.

  • Mockito 사용
    Mock Object의 생성을 도와주는 test framework이다.
    var voucherRepository = mock(VoucherService.class)

Stub, Mock

참고하자!

Hamcrest 이용한 테스트 코드 작성

Spring의 Junit5 지원

단위 테스트 지원

  • without container
  • Mock Objects 지원
  • 의존관계 없이 핵심 로직을 작성하는 것이 중요(비지니스 로직은 프레임워크에 의존적이지 않아야 한다.)

통합 테스트 지원

  • 서버를 띄우지 않고 Bean들간의 interaction을 확인해야한다.
    • 테스트시 Spring 컨테이너가 필요하다. → Spring TestContext Framework 제공
      • Spring TestContext Framework를 사용하여 test 환경에서 ApplicationContext를 쉽게 만들 수 있다. 또한 캐시 기능이 있어 빠르게 테스트를 구동할 수 있다

@ExtendWith + @ContextConfiguration

  • @ExtendWith(SpringExtension.class)
    junit과 상호작용하여 test context와 상호 작용할 수 있도록 만들어준다.

  • @ContextConfiguration OR @ContextConfiguration(classes = {AppConfiguration.class})

    • 어떤식으로 applicationContext가 만들어져야 하는지 알려준다.
    • 별도로 클래스를 찾지 않으면 test 클래스 내부에서 configuration을 찾는다
@ExtendWith(SpringExtension.class)
@ContextConfiguration
public class KdtSpringContextTests {
    @Configuration
    @ComponentScan(
            basePackages = {"org.prgms.kdt.order", "org.prgms.kdt.voucher"}
    )
    static class Config { }

    @Autowired
    ApplicationContext context;

    @Autowired
    OrderService orderService;

    @Autowired
    VoucherRepository voucherRepository;

    // 통합 테스트
    // 실제 빈들을 이용하여 테스트한 것
    @Test
    @DisplayName("orderService를 사용해서 주문을 생성할 수 있다.")
    void testOrderService() {
        // given
        var fixedAmountVoucher = new FixedAmountVoucher(UUID.randomUUID(), 100);
        voucherRepository.insert(fixedAmountVoucher);

        // when
        var order = orderService.createOrder(UUID.randomUUID(), List.of(new OrderItem(UUID.randomUUID(), 200,1 )), fixedAmountVoucher.getVoucherId());

        // then
        assertThat(order.totalAmount(), is(100L));
        assertThat(order.getVoucher().isEmpty(), is(false));
        assertThat(order.getVoucher().get().getVoucherId(), is(fixedAmountVoucher.getVoucherId()));
        assertThat(order.getOrderStatus(), is(OrderStatus.ACCEPTED));
    }

}

@SpringJUnitConfig

  • @SpringJUnitConfig = @ExtendWith + @ContextConfiguration
@SpringJUnitConfig
public class KdtSpringContextTests {

    @Configuration
    @ComponentScan(
            basePackages = {"org.prgms.kdt.order", "org.prgms.kdt.voucher"}
    )
    static class Config { }
    
    ...
}

@ActiveProfiles("프로파일_이름")

테스트시 사용할 프로파일을 설정한다.

profile
꾸준히 나아가자 🐢
post-custom-banner

0개의 댓글