Hyeok의 웹 개발 블로그

<2025.04.24> 테스트 코드 본문

카테고리 없음

<2025.04.24> 테스트 코드

Yhyeok 2025. 4. 24. 22:59

📅  테스트 코드의 중요성과 작성법 정리

1️⃣ 테스트 코드는 무엇이고 왜 작성해야 할까?

소프트웨어 테스트란 해당 소프트웨어가 기대한 대로 잘 동작하는지 확인하는 과정입니다. 개발자라면 누구나 테스트라는 과정을 경험했을 것입니다.

테스트 코드를 작성하면:

  • 소프트웨어의 결함을 조기에 발견할 수 있습니다.
  • 완성도 높은 소프트웨어를 개발할 수 있습니다.
  • 반복적인 테스트를 자동화할 수 있어 시간을 절약할 수 있습니다.
  • 시간이 지날수록 소프트웨어의 안정성이 높아집니다.

테스트 코드 작성의 이점

  1. 테스트를 자주 실행할 수 있다.
  2. 리팩터링 시 안정감을 준다.
  3. 버그를 조기에 발견할 수 있다.

테스트 코드의 FIRST 원칙

원칙의미

F (Fast) 테스트는 빠르게 실행돼야 한다.
I (Isolated) 테스트는 독립적이어야 한다. 외부 시스템에 의존 X
R (Repeatable) 반복 실행해도 결과는 동일해야 한다.
S (Self-validating) 테스트는 스스로 검증 가능해야 한다. (출력 X, 검증 O)
T (Timely) 테스트 코드는 실제 코드보다 먼저 or 동시에 작성되어야 한다.

2️⃣ Spring Boot에서 작성할 수 있는 테스트 종류

테스트 종류 설명
단위 테스트 (Unit Test) 개별 코드 단위 테스트 (순수 Java 코드 위주)
통합 테스트 (Integration Test) 여러 모듈 간 상호작용 테스트 (ex. Repository + Service)
E2E 테스트 (End-to-End Test) API의 처음부터 끝까지 흐름 테스트
인수 테스트 (Acceptance Test) 사용자의 시나리오 전체 플로우 검증 (요구사항 충족 여부 확인)

3️⃣ 테스트 코드 작성 전 기억할 점

  • 테스트의 본질은 시나리오 검증이다.
  • 멋진 코드보단 명확한 시나리오가 더 중요하다.
  • BDD(Given-When-Then) 방식을 염두에 두자.
  • 테스트를 작성하기 전에 한글로 시나리오를 적어보자.

4️⃣ Mocking과 Stubbing

Test Double이란?

테스트에 필요한 가짜 객체

  • Mock: 테스트 전용 가짜 객체 (Dummy, Stub, Spy처럼 동작 가능)
  • Stub: 특정 메서드 호출 시 미리 정의한 응답 반환
  • Spy: 메서드 호출 여부, 횟수 등을 기록
  • Fake: 간단한 가짜 로직 포함 (Stub보다 더 복잡)

Java에서는 Mockito 등의 라이브러리로 Test Double 구현

Mockito 예시

@ExtendWith(MockitoExtension.class)
class SocialMemberServiceTest {

    @Mock
    private SocialMemberRepository socialMemberRepository;

    @InjectMocks
    private SocialMemberService socialMemberService;
}

Mock 객체로 시나리오 테스트

  1. Stubbing
when(memberRepository.findByEmail(any()))
    .thenReturn(Optional.of(new Member(...)));
  1. Spy로 메서드 호출 검증
verify(memberRepository, times(1)).findByEmail(any());
  1. Captor로 파라미터 검증
@Captor ArgumentCaptor<String> emailCaptor;
verify(memberRepository).findByEmail(emailCaptor.capture());
assertThat(emailCaptor.getValue()).isEqualTo("example@email.com");
  1. void 메서드 Stubbing
doNothing().when(memberRepository).delete(any());

5️⃣ 자주 등장하는 객체별 Unit Test 요령

객체 특징 및 테스트 요령
Domain Entity / POJO 순수 단위테스트. Mocking 불필요.
Service 비즈니스 로직 테스트. Mocking 필요. (Repository 등 의존성 대체)
Client 외부 서비스 호출. Mock Server 사용. (MockWebServer, WireMock)
Repository JPA 사용 시 필요 적음. 직접 쿼리(JPQL/QueryDSL) 작성 시 통합 테스트 권장
Controller @WebMvcTest를 이용한 슬라이스 테스트 대체 가능 (우선순위 낮음)

단위 테스트 우선순위

Domain Entity > Application Service > Client > POJO > Repository > Controller

6️⃣ Unit Test 작성 시 주의할 점

  • 의존성 관점
    Repository → Service → Controller 순서로 작성
    (Mock 객체가 믿을만한지 보장 필요)
  • Test Double 사용 시 Stubbing 신뢰성 확보

7️⃣ JPA + H2 Database를 활용한 통합 테스트

  • 통합 테스트는 가볍고 빠르게 실행돼야 한다.
  • @DataJpaTest 사용 → 최소한의 Context 로드
  • 실제 운영 DB 사용 ❌ → Isolated & Repeatable 원칙 위배
    Embedded H2 사용

8️⃣ 기타: 테스트 방법론

방법론 설명
TDD (Test Driven Development) 테스트 → 코드 개발 반복
BDD (Behavior Driven Development) 시나리오 기반 테스트 (Given-When-Then)
ATDD (Acceptance Test Driven Development) 인수 테스트 기반 개발

지금 중요한 건 방법론보다 "일단 테스트 작성"


9️⃣ 마무리

  • 테스트 코드에서 가장 중요한 것은 시나리오 검증
    → 코드를 읽는 사람이 쉽게 이해할 수 있어야 한다.