Post

테스트는 왜 필요할까?

테스트는 왜 필요할까?

Practical Testing: 실용적인 테스트 가이드를 듣고 요약한 내용입니다.

테스트란?

  • 테스트를 하는 이유, 필요한 이유
    • 빠른 피드백
    • 자동화
    • 안정감
  • 테스트 코드가 없다면?
    • 변화가 생기는 매순간마다 발생할 수 있는 모든 Case를 고려해야 한다.
    • 변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야한다.
    • 빠르게 변화하는 소프트웨어의 안정성을 보장할 수 없다.
  • 테스트 코드가 병목이 된다면
    • 프로덕션 코드의 안정성을 제공하기 힘들다.
    • 테스트 코드 자체가 유지보수하기 어려운, 새로운 짐이 된다.
    • 잘못된 검증이 이루어질 가능성이 생긴다.
  • 올바른 테스트 코드란?
    • 자동화 테스트
      • 빠른 시간 안에 버그를 발견
      • 비용을 절약
    • 소프트웨어의 빠른 변화를 지원
    • 팀 차원의 이익
    • 단기적으론 느리지만, 장기적으로는 빠르다.

단위 테스트

  • 작은 코드 단위를 독립적으로 검증하는 테스트
  • 빠름
  • 안정적

JUnit 5

AssertJ / Fluent assertions for java

AssertJ

  • 테스트 코드 작성을 원활하게 돕는 테스트 라이브러리
  • 풍부한 API, 메서드 체이닝 지원

테스트 케이스 세분화하기

  • 테스트 코드 작성 전에 암묵적이거나 아직 드러나지 않은 요구사항이 있는가? 생각해보자
    • 금액이 0 이하인가?
    • 수량이 0 이하인가?
  • 해피 케이스와 예외 케이스
    • 경계값 테스트가 중요하다.

테스트하기 어려운 영역을 분리하기

  • 테스트 할 때마다 변경되는 값이 있다면, 테스트를 정상적으로 할 수 없다.
  • 테스트 하고자 하는 영역을 잘 구분하자
  • 외부로 분리할수록 테스트 가능한 코드는 많아진다.
  • 테스트하기 어려운 영역이란?
    • 관측할 때마다 다른 값에 의존하는 코드
      • 현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력 등
    • 외부 세계에 영향을 주는 코드
      • 표준 출력, 메시지 발송, 데이터베이스에 기록하기 등
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// BAD
public Order createOrder() {
    LocalDateTime currentDateTime = LocalDateTime.now();
    LocalTime currentTime = currentDateTime.toLocalTime();

    if (currentTime.isBefore(SHOP_OPEN_TIME) || currentTime.isAfter(SHOP_CLOSE_TIME)) {
        throw new IllegalArgumentException("주문 시간이 아닙니다.");
    }

    return new Order(currentDateTime, beverages);
}

// GOOD
public Order createOrder(LocalDateTime currentDateTime) {
    LocalTime currentTime = currentDateTime.toLocalTime();

    if (currentTime.isBefore(SHOP_OPEN_TIME) || currentTime.isAfter(SHOP_CLOSE_TIME)) {
        throw new IllegalArgumentException("주문 시간이 아닙니다.");
    }

    return new Order(currentDateTime, beverages);
}
This post is licensed under CC BY 4.0 by the author.