-
TC(Test Case) & JUnitSTUDY/백엔드 2020. 12. 18. 17:45
JUnit
- Java에서 독립된 단위 테스트(Unit Test)를 지원해주는 프레임워크이다.
- 특징
- @Test 메서드를 호출할 때 마다 새로운 인스턴스를 생성하여 독립적인 테스트가 이루어진다.
- Test마다 경과 시간이 나오기 때문에 최적화된 코드를 유추할 수 있다.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>- 지원하는 Annotation
- @Test - 테스트를 실행하는 메소드로 선언 JUnit은 각각의 테스트가 서로 영향을 주지 않고 독립적으로 실행되며 @Test마다 개체를 생성해서 내부적으로 실행된다.
- @Disabled / @Ignore - 테스트를 실행하지 않는 메소드로 선언
- @BeforeEach / @Before - @Test 메소드가 실행되기 전에 실행된다. 주로, 공통으로 사용하는 부분을 선언한다.
- @AfterEach / @After - @Test 메소드가 실행된 후에 실행된다. 주로, 테스트시 사용한 자원을 해제할 때 사용한다.
- @BeforeAll / @BeforeClass - @Test 메소드보다 먼저 한 번만 수행되어야 할 경우에 사용한다.
- @AfterAll / @AfterClass - @Test 메소드보다 나중에 한 번만 수행해야할 때 사용한다.
*실행 코드
@BeforeEach
void beforeEach(){ System.out.println("@BeforeEach 수행");}
@BeforeAll
void beforeAll(){ System.out.println("@BeforeAll 수행");}
@AfterEach
void afterEach(){ System.out.println("@AfterEach 수행");}
@AfterAll
void afterAll(){ System.out.println("@AfterAll 수행");}
@Test
void beforeAndAfterTest(){ System.out.println("before and after test");}
@Test
void printHelloWorld() throws Exception {
String word = "Hello World";
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string(word))
.andDo(print());
}
*결과*
@BeforeAll 수행
@BeforeEach 수행
printHelloWorld() 수행 // 실제 controller method
@AfterEach 수행
@BeforeEach 수행
beforeAndAfterTest()
@AfterEach 수행
@AfterAll 수행- JUnit 5 User Guide
- 참고
- 다른 사용법 : gmlwjd9405.github.io/2019/11/26/junit5-guide-basic.html
- MockMvc 관련 블로그
- Test Code가 중요한 이유 : Test code 자체가 Documentation이다.
- API 사용법에 대한 기술
- 하나의 예제가 되어준다.
- 어떤 데이터가 in, out 되는지 확인할 수 있다.
- 해당 함수에서 어떠한 결과들이 나오는지 모두 확인할 수 있다.
- 참고
- Constructor Test : 단순한 로직의 경우 굳이 테스트하지 않는다. 단 값을 초기화하거나 Load하는 경우가 있을 때는 테스트를 수행한다.
- Getter / Setter Test : 단순한 Getter / Setter는 굳이 테스트하지 않는다. 로직이 있는 경우에는 로직을 별도의 메소드로 분리하고 이를 테스트하는 것이 좋다.
- Boundary Test : Null에 대한 확인, Default 값에 대한 확인, 범위가 있는 경우 MIN/MAX 값에 대한 확인을 목적으로 한다. 이 경우엔 결국 NullPointerException이 발생하지 않도록 방어 혹은 검증 로직을 보완하는 것이 바람직하다.
- Exception Test : 예측한 예외가 실제로 발생하는지 확인한다. try/catch문이 아닌 단순 어노테이션 설정만으로 간단하게 확인할 수 있다.
더보기@Test (expected = NullPointerException.class)
public void testException() {
throw new NullPointerException();
}
- Equality Test - value와 reference 비교
더보기@Test
public void testReferenceEqual() {
String str1 = new String("someValue");
String str2 = str1;
assertEquals("same value", str1, str2);
assertSame("same reference", str1, string2);
}
- Equality Test - 숫자값 비교
더보기@Test
public void testDoubleEqual() {
double num1= 10 / 6;
double num2 = 1.66666;
assertEquals("소수 다섯번째까지 같음", num1, num2, 5);
}
- Equality Test - 리스트/배열의 비교
더보기@Test
public void testListEqual() {
List list1 = Arrays.asList("a", "b", "c");
List list2 = Arrays.asList("a", "b", "c");
assertEquals("리스트의 값과 순서가 같음", list1, list2);
}
@Test
publicvoidtestArrayEqual(){
String[]arr1=newString[]{"a","b","c"};
String[]arr2=newString[]{"a","b","c"};
assertArrayEquals("배열의 값과 순서가 같음", arr1, arr2);
}
- Equality Test - Value Object의 비교
더보기@Test
public void testObjectEqual() {
UserVo user1 = new UserVo(25, "gildong", "hi");
UserVo user2 = new UserVo(25, "gildong", "hi");
assertEquals(user1.getAge(), user2.getAge());
assertEquals(user1.getName(), user2.getName());
assertEquals(user1.getDescription(), user2.getDescription());
}
- Parameterized Test : parameter 값만 바꿔가면서 동일한 테스트를 반복해서 수행하고 싶을 때 유용하다.
- Timeout Test : 테스트에 걸리는 시간을 지정해서, 해당 시간을 넘길 경우 Fail 처리를 할 수 있다.
더보기@Test (timeout = 1)
public void testTimeout() { }
- Test Ignore : 테스트를 안하고 싶을 때 사용한다. 클래스와 메소드 단위 모두 사용 가능하다.
더보기@Ignore ("클래스 단위로 테스트를 수행하지 않도록 설정(실제론 상세 원인을 표시)")
public class IgnoreTest {
@Test
public void testIgnored() {
assertTrue("모든 테스트 메소드는 실행이 되지 않음", true);
}
}
@Ignore ("메소드 단위로 테스트 수행하지 않도록 설정(실제론 상세 원인을 표시)")
@Test
public void testIgnore() {
assertTrue("이 테스트 메소드는 실행이 되지 않음", true);
}
1. 통합 테스트 - @SpringBootTest
모든 빈을 등록하여 테스트를 진행한다. 그렇기 때문에 애플리케이션 규모가 크면 테스트가 많이 느려진다.
- @RunWith : 해당 어노테이션을 사용하면 JUnit의 러너를 사용하는게 아니라 지정된 SpringRunner 클래스를 사용한다.
- @SpringBootTest
- @EnableConfigurationProperties : Configuration으로 사용하는 클래스를 빈으로 등록할 수 있게 해줌.
- ( Enable support for {@link ConfigurationProperties} annotated beans. )
2. 컨트롤러 테스트 - @WebMvcTest
- 웹상에서 요청과 응답에 대한 테스트를 할 수 있다. 해당 어노테이션을 사용하면, @Controller, @ControllerAdvice, @JsonComponent와 Filter, WebMvcConfiguer, HandlerMethodArgumentResolver만 로드되기 때문에 전체 테스트보다는 가볍다.
3. JPA 관련 테스트 - @DataJpaTest
- JPA 관련된 설정만 로드한다. 그렇기 때문에 @Entity 클래스를 스캔하여 스프링 데이터 JPA 저장소를 구성한다. 기본적으로 인메모리 데이터베이스를 이용함. 데이터소스의 설정이 정상적인지, JPA를 사용하서 데이터를 제대로 생성, 수정, 삭제하는지 등의 테스트가 가능함.
- @AutoConfigureTestDataBase : 데이터 소스를 어떤 걸로 사용할지에 대한 설정
- Replace.Any : 기본적으로 내장된 데이터소스를 사용
- Replace.NONE : @ActiveProfiles 기준으로 프로파일이 설정됨
- @DataJpaTest : 테스트가 끝날 때마다 자동으로 테스트에 사용한 데이터를 롤백
4. REST 관련 테스트 - @RestClientTest
- Rest 통신의 JSON 형식이 예상대로 응답을 반환하는지 등을 테스트 함
- @RestClientTest : 테스트 대상이 되는 빈을 주입받음
- @Rule
- MockRestServiceServer : 클라이언트와 서버 사이의 REST 테스트를 위한 객체. 내부에서 RestTemplate을 바인딩하여 실제로 통신이 이루어지게끔 구성할 수 있음.
5. Json의 직렬화, 역직렬화 테스트 - @JsonTest
- Gson, Jackson의 테스트를 제공함.
6. JUnit5에 추가된 내용
- @DisplayName : method 명으로 표현하기 부족했다면 해당 어노테이션을 유용하게 사용할 수 있다.
- Lifecycle Method
- @BeforeClass, @AfterClass -> @BeforeAll, @AfterAll
- @Before, @After -> @BeforeEache, @AfterEach
- 중첩된 테스트 클래스 - @Nested
7. 참고
'STUDY > 백엔드' 카테고리의 다른 글
Bean (0) 2021.01.05 Mybatis (0) 2020.12.31 Server Log (0) 2020.12.28 Apache Spring boot(내부 tomcat) 연동 (0) 2020.12.24 WEB 서버와 WAS (0) 2020.12.17