Contents
JUnit은 기본 전략으로 테스트 메소드마다 테스트 인스턴스를 새로 만든다. 테스트 메소드를 독립적으로 실행해서 예상하지 못한 부작용을 방지하기 위한 전략이다.
1. 기본 전략 : 메소드마다 인스턴스 생성
예를 들어, 전역변수를 생성해서 각 메소드에서 값을 변화해도, 초기값으로 계속 남아있다.
각 메소드에서 this를 출력해보면 객체가 다른 것도 확인이 가능하다.
public class InstanceTest {
int value = 1;
@Test
void check_instance1(){
System.out.println("1 : " + this.toString() +", value : " + (value++));
}
@Test
void check_instance2(){
System.out.println("2 : " + this.toString() +", value : " + (value++));
}
}
테스트 간의 의존성을 없애기 위해서이며, 테스트 순서에 의해 인스턴스 값이 바뀌면 불안정해진다.
테스트 순서는 예측을 할 수가 없다. (JUnit5부터는 선언되는 순으로 실행되기는 한다.)
따라서 테스트간 의존성은 없애는 것이 좋다.
2. @TestInstance(Lifecycle.PER_CLASS) : 클래스 1개당 인스턴스 생성
- JUnit 5에서는 기본 전략을 변경할 수 있다.
클래스에 @TestInstance(Lifecycle.PER_CLASS)를 붙이면 클래스당 인스턴스를 하나만 만들어 사용한다.
- 클래스당 인스턴스를 하나만 만들면 @BeforeAll과 @AfterAll를 default 메소드로 정의할 수 있다. 즉, 꼭 static일 필요가 없다.
테스트를 해보면
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class InstanceTest {
int value = 1;
@Test
void check_instance1(){
System.out.println("1 : " + this.toString() +", value : " + (value++));
}
@Test
void check_instance2(){
System.out.println("2 : " + this.toString() +", value : " + (value++));
}
}
클래스 인스턴스를 하나만 만들어서 value값이 증가한 것을 볼 수 있다.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class InstanceTest {
int value = 1;
@Test
void check_instance1(){
System.out.println("1 : " + this.toString() +", value : " + (value++));
}
@Test
void check_instance2(){
System.out.println("2 : " + this.toString() +", value : " + (value++));
}
@BeforeAll
void beforeAll(){
System.out.println("시작 시 한 번 실행");
}
@AfterAll
void afterAll(){
System.out.println("종료 시 한 번 실행");
}
}
@BeforAll과 @AfterAll에 static을 적지 않아도 된다.
3. @TestMethodOrder : 테스트 순서 지정
- JUnit5부터는 작성한 테스트 메소드 순서대로 실행되기는 하지만, 이에 의존해서는 안된다.
테스트 인스턴스를 메소드마다 새로 만드는 것처럼 테스트 간의 의존성을 막기 위함인데, JUnit5 내부 로직 구성에 따라 언제든지 변경될 수 있다.
- 하지만 종종 순서에 따라 테스트를 수행해야하는 경우가 있다.
예) 인수테스트, 특정 기능, 시나리오 테스트(회원가입, use 케이스 등)
이 때 @TestMethodOrder를 사용하는데 @TestInstance(Lifecycle.PER_CLASS) 를 같이 사용하는 게 좋다. (필수x)
@TestMethodOrder
- Alphanumeric :
- OrderAnnotation : 순서에 따라 실행 (org.junit.jupiter.api)
- Random :
// Order는 낮을 수록 우선순위가 높다.
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class OrderTest {
int value = 1;
@Test
@Order(3)
void check_instance1(){
System.out.println("1 : " + this.toString() +", value : " + (value++));
}
@Test
@Order(1)
void check_instance2(){
System.out.println("2 : " + this.toString() +", value : " + (value++));
}
@Test
@Order(2)
void check_instance3() {
System.out.println("3 : " + this.toString() + ", value : " + (value++));
}
@Test
@Order(1)
void check_instance4() {
System.out.println("4 : " + this.toString() + ", value : " + (value++));
}
}
우선순위가 같은 경우에는 무작위로 실행된다. (그래도 같은 숫자를 주지 말자)
출처 : '더 자바, 애플리케이션을 테스트하는 다양한 방법'(백기선), 자료&11~12강
'Java & Spring' 카테고리의 다른 글
[Java Test] 5. Chaos Monkey 운영 이슈 테스트 (0) | 2023.05.25 |
---|---|
[Java Test] 4. Jmeter 성능테스트 (0) | 2023.05.25 |
[Java Test] 2. Mockito (0) | 2023.05.22 |
[Java Test] 1. JUnit5 (4) properties, 확장, 마이그레이션 (0) | 2023.05.22 |
[Java Test] 1. JUnit5 (2) 테스트 필터링, 테스트 반복 (1) | 2023.05.19 |
[Java Test] 1. JUnit5 (1) (0) | 2023.05.18 |
[DDD] 도메인 주도 개발 - (3) 리포지토리 & 모델 구현 (0) | 2023.02.21 |
[DDD] 도메인 주도 개발 - (2) 애그리거트 (0) | 2023.02.21 |