[테스트 코드] 단위테스트

말하는 감자·2024년 11월 9일
1
post-thumbnail

[Practical Testing: 실용적인 테스트 가이드]

섹션 3. 단위테스트

📌 단위테스트

: 작은 코드 단위를 독립적으로 검증하는 테스트
작은 코드 : 클레스 or 매서드

  • 검증 속도가 빠르고 안정적

📍 JUnit 5

: 단위 테스트를 위한 테스트 프레임워크
5는 버전이며 언어에 따라 이름이 변경됨 (XUnit)

📍 AssertJ

: 테스트 코드 작성을 원할하게 돕는 테스트 라이브러리

  • 풍부한 API, 메서드 체이닝 지원

assertEquals(a, b) : Junit의 assert문 a와 b가 같은지
assertThat(a).isEquaslTo(b) : AssertJ API사용 / 이게 보다 명시적. 메서드 체이닝 가능

📌 테스트 케이스 세분화하기

  • 해피 케이스 : 요구사항을 그대로 만족하는 테스트 케이스
  • 예외 케이스 : 요구사항에 없었으나 암묵적인 테스트 케이스 (ex 아메리카노 0잔, 라떼 -1잔)

경계값 테스트 - 범위(이상, 이하, 초과, 미만), 구간, 날짜 등

테스트 케이스를 세분화 한 다음에 경계값이 존재하는 경우에는 경계값에서 항상 테스트 할 수 있도록 고민하는 게 중요하다.

예외 테스트는 assertThatThrownBy() 사용
isInstanceOf()에 발생할 오류 삽입
hasMessage()에서 메시지 검증

assertThatThrownBy(() -> cafeKiosk.add(americano, 0)
	.isInstanceOf(IllegalArgumentException.class)
	.hasMessage("음료는 1잔 이상 주문하실 수 없습니다.");

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

테스트 가능한 코드가 있을 때 현재의 일시를 가지고 제약 조건을 걸게 되면 테스트가 어려운 코드가 들어오게 된다. 그렇게 되면 전체가 테스트 불가능한 상태가 된다. 그래서 테스트를 수행할 때마다 값이 달라져서 테스트의 성공여부를 예상할 수 없게 된다.

조치 방안으로 테스트 어려운 영역을 외부로 분리한다. LocalDateTime을 외부에서 받도록 파라미터를 분리해서 실제 CafeKioskRunner에서 수행할 때는 프로덕션 코드에 LocalDateTime.now()를 넣어서 원하는 기능을 동작하도록 하고 테스트 코드에서는 우리가 원하는 코드를 넣어준다.

❓ 이렇게 테스트해도 되는가요?

❗ 우리가 검증하고자 하는 것은 LocalDateTime.now()가 아니다. 테스트하고자 하는 영역은 어떤 시간이 주어졌을 때 이 시간 범위 안에 이 시간이 들어오는지 여부가 중요하다.

테스트 코드 상에서 원하는 값을 넣어줄 수 있도록 설계를 변경하는 것이 중요하다.
테스트 어려운 영역을 외부로 분리할수록 테스트 가능한 코드는 많아진다.

📍 테스트하기 어려운 영역

  • 관측할 때마다 다른 값에 의존하는 코드 ex) 현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력 등
  • 외부 세계에 영향을 주는 코드 ex) 표준 출력, 메시지 발송, 데이터베이스, 파일에 기록하기 등

📍 테스트 하기 쉬운 영역

순수함수 (pure functions)

  • 같은 입력에는 항상 같은 결과
  • 외부 세상과 단절된 형태
  • 테스트하기 쉬운 코드

📑 출처

profile
나는 말하는 감자다

0개의 댓글