본문 바로가기
프레임워크/Spring

테스트코드 알아보기

by taeung515 2025. 6. 12.

테스트를 왜 해야 할까?

기능이 요구사항대로 잘 동작하고 있는지 확인해야하기 때문입니다.

- 아무리 훌륭한 개발자여도 한번에 완벽한 코드를 구현한다는 것은 매우 어려운 일이고, 생각하지 못한 입력으로 인해 기능장애가 발생할 수 있기 때문에 다양한 케이스를 테스트를 통해 검증해야합니다.

 

테스트방법

  1.  Swagger, Postman등을 통해 여러 케이스들을 확인해보며 테스트를 진행
  2. QA 과정을 통해 UI, Front, Server까지 한번에 테스트
  3. 테스트 코드를 만들어 테스트 진행

테스트 코드는 왜 필요할까?

  1. 버그를 조기에 발견할 수 있다.
  2. 코드 품질을 개선할 수 있다.
  3. 배포단계에서의 안정성을 보장해준다.
  4. 코드 리펙토링이 쉬워지고 개선 하는것에 주저함이 없어진다.
    • 현재 운용중인 코드의 성능 개선 또는 가독성/구조 개선차원에서 리펙토링을 진행하려고 할 때 테스트 코드가 존재하지 않다면 변경한 코드들이 기존과 같이 동작을 하는지 확인이 없어 모든 상황을 테스트 해야한다.
  5. 시간이 지날 수록 테스트를 해야하는 기능들이 많아진다.

    • 서비스가 발전함에 따라 추가/변경되는 기능들이 너무 많아 사람이 테스트 하기에는 중요도에 비해 시간을 할애하기 어려워진다.
    • 테스트 코드가 충분히 있다면 새로운 기능을 개발하거나 수정할때 기존에 있던 기능들은 테스트코드에 의해서 동작이 확인되지만 테스트 코드가 없다면 어느 범위까지 사이드 이펙트가 발생할지 찾고 테스트를 다시 수행해야 하는 불편함이 존재한다.
    • 충분한 테스트 코드로 기존 코드가 잘 동작하고 있다는 것을 확인해야 한다. -> 회귀 테스트

테스트 코드 작성의 원칙

1. FIRST 원칙

  • F(Fast)
    • 테스트 코드는 빠르게 실행되어야 한다.
  • I (Isolated)
    • 테스트는 독립적이어야 한다.
  • R (Repeatable)
    • 테스트 코드는 반복 실행해도 항상 동일한 결과여야 한다.
  • S (Self-validating)
    • 테스트 코드는 그 자체로 스스로 검증되어야한다.
  • T (Timely)
    • 테스트 코드는 즉시 작성되어야한다.

2. 테스팅 7원칙

  1. 테스트는 결함의 존재를 찾는 행위이다.
  2. 완벽한 테스트는 불가능하다.
  3. 테스트 구성은 가능한 빠르게 시작한다.
  4. 결함은 집중된다.
  5. 살충제 역설.
  6. 테스트는 정황에 의존적이다.
  7. 오류가 부재함은 궤변이다.

테스트의 종류

위로 갈수록 테스트 비용이 비싸지고 속도는 감소한다.


테스트 실습

우선 Given When Then 패턴을 간략하게 알아보자

  • Given: 테스트에 필요한 변수를 정의하거나 Mock 객체를통해 특정 상황 또는 행동을 정의합니다.
  • When: 실제 테스트를 하는 메소드가 호출되며 테스트를 통한 결괏값을 가져옵니다.
  • Then: When 단계에서 나온 결괏값을 검증하는 작업을 수행합니다.

주로 우리는 서비스계층(도메인 모델 및 알고리즘) 부분에 테스트 코드를 작성한다.

 

테스트를 위한 어노테이션

1. @DataJpaTest

  • JPA와 관련된 Component들만 모두 가지고와 Repository Layer 단위 테스트를 위한 Annotation이다.
  • 기본적으로 In-memory DB(ex H2)를 사용하여 테스팅

2. @ExtendWith

  • Junit5 환경에서 확장기능을 사용할때 사용.
  • 주로 MockitoExtension 과 함께 Service Layer, 클래스 단위 테스트에 사용

3. @WebMvcTest

  • 스프링의 Web Layer(controller, filter 등)을 테스트하기 위한 Annotation이다.
  • @Controller, @ControllerAdvice 등 웹과 관련된 Bean만 로드하여 테스트를 수행한다.

4. @SpringBootTest

  • 스프링 부트 전체를 테스트 수행하기 위해서 사용하는 Annotation이다.
  • 서버를 실행하듯 모든 스프링 Context를 로드한다.

단위 테스트 작성

  • 의존성은 Mock 객체를 통해 Mocking을 하여 분리를 한다.
  • 테스트는 의존성 안쪽부터 진행한다.
    • 단위테스트는 의존성을 제거하기 때문에 의존하고 있는 클래스가 정상적으로 동작하고 있다는 것을 확신해야한다.
    • Repository -> Service -> Controller 순서로 테스트 코드 작성!
  • 데이터 준비단계(Given)가 너무 복잡하거나 길어지면 테스트코드 가독성에 문제가 발생 할 수 있으니 FixtureMonkey 등을 사용하여 불필요한 내용 간소화를 한다.

커버리지 향상 vs 의미있는 테스트 코드만 작성

테스트 커버리지는 하나의 참고 지표일 뿐이다. 중요한 것은 커버리지를 위해 의미 없는 테스트를 만들지 않는 것.테스트는 버그를 막기 위한 도구이자, 팀원이 코드를 신뢰할 수 있게 만드는 가장 실용적인 문서이다. 가능하면 커버리지를 일정 수준 유지하되,

의미 없는 테스트는 과감히 생략하고, 중요한 흐름에 집중한 테스트를 작성하는 것이 실전적인 선택이다.

 

의미있는 테스트?

  • 비지니스 로직의 핵심 흐름을 검증
  • 실패 케이스나 예외 상황을 명확하게 설명하는 역할
  • 리팩토링 시에도 깨지지 않고 신뢰할 수 있는 테스트

'프레임워크 > Spring' 카테고리의 다른 글

JWT, Spring security  (0) 2025.06.23
Spring Boot에서 AOP와 Interceptor를 활용한 로깅 방법  (0) 2025.06.12
필터에서 예외처리  (0) 2025.06.12