[SpringBoot] 이거 잘 돌아가는거 맞나..?@DataJPATest 로 테스트 코드 알아보기

JUNHYUK CHANG·2024년 2월 8일
0

TIL

목록 보기
18/33

테스트 코드란 ?

그동안 각종 Service 와 메서드를 구현하면서 예상대로 동작하는지 확인해보기 위해 수없이 테스트를 해왔다. 하지만 매번 실행해보면서 결과를 눈으로 확인하여 해석하고, 다른 값을 넣고 다시 빌드하는 것은 번거롭기도 하고 귀찮기도 하기 때문에 점점 테스트 횟수가 줄어들고, 다 완성한 다음에야 테스트를 해보며 오류를 수정해나가는 경우도 많았다. 그렇게 B 기능을 완성했는데 A 기능도 다시 검사해봐야 한다면..?

이런 번거로운 과정을 테스트 코드를 작성하여 자동화 한다면 쉽게 테스트를 해볼 수 있고, 예상되는 오류나 다양한 상황을 연출할 수도 있기 때문에 개발에 큰 도움이 되는 과정이라고 볼 수 있다.

테스트 코드를 작성하면서 얻을 수 있는 장점

  1. 테스트를 수시로 수행하며 조기에 버그를 발견할 수 있다!
  2. 리팩토링 시 테스트 코드가 실패한 다면 변경한 코드의 문제인 것을 확인할 수 있다!
  3. 테스트 코드를 통해 코드의 동작을 쉽게 이해할 수 있어 문서화 하는 역할을 겸한다!
  4. 테스트 코드 작성을 통해 다양한 시나리오를 고려해보면서 올바른 설계에 대한 고민을 할 수 있다!
  5. 그 외에도 소프트웨어의 안정성 향상과 품질 향상에 다양한 도움이 된다 !

FIRST 원칙

  • F (Fast)
    • 테스트 코드는 빠르게 실행되어야 한다.
  • I (Isolated)
    • 테스트는 독립적이어야 한다. 즉, 다른 테스트나 외부 시스템을 의존하면 안된다.
    • 예를 들어, 카카오 로그인을 위해 카카오 시스템을 의존하는 코드가 있을 때 이 의존성을 제거하지 못하면 카카오 서버의 상태가 내 테스트 코드 결과에 영향을 줄 수 있다.
  • R (Repeatable)
    • 테스트는 반복실행해도 동일한 결과여야한다.
    • 예를 들어, 테스트 코드에 LocalDateTime.now() 와 같은 코드를 사용한다면 해당 테스트 코드는 시간이 지났을 때 실패할 가능성이 있다.
  • S (Self-Validating)
    • 테스트는 스스로 검증되어야한다. 테스트 결과를 검증하기 위해 별도 리소스가 들어가서는 안된다.
    • 예를 들어, 사용자가 직접 테스트 결과를 눈으로 확인하는 작업이 필요해서는 안된다. 테스트 코드만으로 충분히 검증되어 사람은 테스트 결과만 확인할 수 있도록 만들어야한다.
  • T (Timely)
    • 테스트 코드는 가능한 빨리 작성되어야한다.
    • 즉, 테스트 코드를 작성할 비즈니스 로직이 작성된 후 테스트 코드를 작성하기까지의 시간이 너무 길면 안된다는 말이다.

@DataJpaTest 란?

  • DB와 JPA 와 관련된 자동 설정들을 추가해줌으로써 테스트 코드 작성에 필요한 작업들을 처리해준다.
  • JPA 관련 기능 테스트 시 유용.
  • 어플리케이션의 일부만 로드하여 테스트 하기 때문에 속도가 빠름.
  • 실제 DB 엔 영향을 주지 않음
  • @SpringBootTest 는 전체 어플리케이션 컨텍스트를 로드하므로 통합 테스트에 적절하고, 모든 빈을 포함하여 테스트 할 수 있다는 장점이 있지만 그만큼 구성하는데에 시간이 걸린다는 단점이 있다.

@DataJpaTest 의 역할

  1. Entity 객체와 Repository 를 스캔해 Bean 으로 등록해준다.
  2. show-sql 옵션을 통해 SQL 쿼리문을 볼 수 있게 해준다.
    -가급적 SQL 쿼리를 확인하며 눈에 익히는 것이 좋다 !
  3. 모든 테스트 코드에 @Transactional 을 붙여 성공시에만 반영될 수 있도록 한다.
  4. 기존 DataSource 를 교체하고 인메모리 데이터베이스( 1회용. 휘발성 ) 를 구성 및 실행해준다.
  • @AutoConfigureTestDatabase 가 해주는 일
  • 보통 해당 설정은 비활성화 한 후 테스트 코드용 H2 DB 혹은 MySQL 을 실행시켜 테스트한다.
  1. Test용 EntityManager 를 생성해준다!

    특히 @Transactional 이 적용되기 때문에 변동사항이 생기더라도 바로 반영되지 않고 '쓰기지연 SQL 저장소' 에 쌓일 뿐이다. 실제로 쿼리문을 발생시켜야 한다면 flush() 를 직접 호출해야 한다! ( TestEntityManager 를 주입받아 호출할 수 있다. entityManager.flush())

개발 중간중간 테스트 코드를 작성하는 것은 다소 귀찮은 일이지만, 직접 실행하며 결과값을 확인하고 문제점을 파악하는 것은 더 비효율적인 일이 될 수 있다. 프로젝트의 각 기능을 빠르게 검증하여 안정성을 높이는 테스트 코드 작성을 잘 습득하여 유용하게 사용할 수 있어야겠다. 다음 포스트에서 @DataJpaTest 를 활용한 단위 테스트에 대해 알아보자!

0개의 댓글