| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- 스프링 부트
- JWT
- @ComponentScan
- JdbcTemplate
- Spring Container
- @Transactional
- redis
- docker
- 서블릿 컨테이너
- DI
- Spring
- kafka
- AWS
- JPQL
- 페이징
- dockerhub
- CORS
- Routing Key
- 지연 로딩
- Spring Data JPA
- securitycontextholderfilter
- mybatis
- 컨테이너
- MSA
- docker compose
- Web
- Dead Letter Queue
- 쿠버네티스
- JPA
- DLQ
- Today
- Total
look-forest
테스트의 종류 본문
테스트 코드를 만들어야하는 이유
테스트해보기 위해 직접 실행하면,
오래 걸리고, 반복 실행하기 어렵고, 여러 테스트를 한번에 실행하기 어렵다!
이를 해결하기 위해 자바에서는 JUnit이라는 프레임워크로 테스트를 실행한다
그리고 리팩토링 시 유용하다!
테스트 코드의 범위
- 코드: 코드에 오류가 없는가?
- Class: 이 클래스는 어떤 역할을 하는가?
- 시스템: 어떤 서비스를 제공하는가?
- 고객: 정상적으로 회원가입과 로그인이 되는가?
테스트 종류
- 단위 테스트: 코드가 제대로 기능하는지 확인하기 위해 개별 모듈을 독립적으로 테스트
- 통합 테스트: 다른 모듈이 결합될 때 잘 작동하는 지 테스트
- E2E 테스트: 사용자 관점에서 처음부터 끝까지 제대로 작동하는지 확인하는 테스트
- 인수 테스트: 고객 요구사항 충족 여부 확인
※ TDD: 테스트를 먼저 작성하고 개발
단위 테스트
기본 예제
repository의 input/output test를 해보자
1. 먼저 테스트할 객체를 만들어줘야 한다.

2. 테스트 메소드를 만든다.

주의할 점
테스트 메소드들은 순서와 상관없이 서로에게 영향을 미치지 않도록 설계해야 한다.
DB에 값이 누적되거나 공용 전역 변수를 사용하면 순서가 영향을 줄 수 있다.
따라서 테스트 후에 공용 데이터, DB 등을 초기화 해줘야 한다.
이를 위해 @AfterEach를 사용해 각각 test 메소드가 끝나고 실행될 콜백 메소드를 작성한다.

테스트 프레임워크를 쓰면, 프레임워크의 라이프 사이클을 따른다.
@BeforeEach, @AfterEach 등 애노테이션을 붙여 라이프 사이클 단계에서 콜백 식으로 호출될 메소드를 정할 수 있다.
Test Case의 기본 틀
given / when / then 형식으로 생각하면 짜기 쉽다
~인 상황이 주어졌다 / 테스트할 기능을 실행할 때 / 결과가 옳은가?

※ Tip: 예외를 던질 경우
기본적으로 예외 처리는 try-catch문을 사용해왔을 것이다

assertj는 try-catch보다 편리한 방법을 제공한다!

예외가 발생하지 않거나 다른 예외가 발생하면 실패!
테스트할 때 발생한 문제 상황 예시
테스트는 개별적으로 수행되어야 한다는 원칙을 지키기 위해 매번 memberRepository를 비웠다.

그런데 memberService가 사용하는 memberRespository와
test 인스턴스에서 사용하는 memberRepository는 다른 인스턴스이다..

서비스 클래스는 비즈니스 로직을 관장하는데, 테스트 만을 위해
MemberService에서 직접 memberRepository의 clearStore()을 호출하는 메소드를 만들긴 애매하다..
해결
같은 repository를 사용하도록 의존성을 외부에서 주입하면 된다!

통합 테스트
실제로 DB와 잘 연동되는지 스프링을 띄워서 테스트해보자
통합 테스트는 실제로 스프링을 띄우기 때문에 느리다.
반면 단위 테스트는 순수 java 코드만 실행하므로 빠르다!
@SpringBootTest
스프링 컨테이너와 테스트를 함께 실행한다

문제 발생
테스트를 실행하면 처음엔 정상 실행된다.
하지만 두번째부터는 에러가 발생한다.

앞 테스트에서 이미 같은 데이터를 넣었기 때문이다.
test는 반복할 수 있어야 한다
따라서 각 테스트 메소드가 끝나고 DB를 Rollback해야 한다. ※DB는 commit해야 DB에 반영된다
해결: @Transactional
이를 위해 @Transactional을 붙인다.
테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백한다.

이렇게 하면 DB에 데이터가 남지 않아 다음 테스트에 영향을 주지 않는다.
※ @Transactional이 service 등에 붙을 땐 롤백x. test에서 붙일 때만 롤백한다.
옵션으로 메소드에 @Commit을 붙이면 DB에 반영된다.
참고 자료
스프링 입문(김영한 님)
'Test > 애플리케이션을 테스트하는 다양한 방법' 카테고리의 다른 글
| Web MVC / Security / JPA 관련 test (0) | 2024.12.15 |
|---|---|
| Mockito (0) | 2024.11.10 |
| Junit 5 (2) | 2024.11.10 |
| 테스트 - DB 연동 (0) | 2024.08.17 |