2020-12-5 백기선님 더자바 테스트(1) 강의정리 Junit
Junit
- 자바에서 가장 많이 사용하는 테스트 프레임워크, 자바8이상을 필요로 한다.
- 스프링부트 2.2부터는 Junit5가 기본적으로 의존성에 추가된다.
- 출처 : https://goodgid.github.io/Junit5-Intro-Structure/
- Platform : 테스트를 실행하는런처 제공. TestEngine API 제공
- Jupiter : TestEngine API 구현체로 JUnit 5를 제공
- Vintage : Junit 3,4를 지원하는 TestEngine 구현체
시작하기
-
클래스를 만들고 클래스 이름위에 cmd + shift + T를 누르면 적절한 위치에 테스트클래스가 생성된다.
-
Junit5부터는 클래스, 메서드가 public일 필요가 없다.
-
@BeforeAll, @AfterAll를 할때는 static 선언을 해야한다.
-
package me.jimmy.test; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.assertNotNull; @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class StudyTest { @Test @Disabled public void disabledTest() { System.out.printf("실행 안되는 테스트"); } @Test public void create_new_study() { Study study = new Study(); assertNotNull(study); } @Test @DisplayName("스터디 이름 명명 테스트 어노테이션") void create1() { System.out.println("create1"); } @BeforeAll static void beforeAll() { System.out.println("before All"); } @AfterAll static void afterAll() { System.out.println("After all"); } @BeforeEach void beforeEach() { System.out.println("before Each"); } @AfterEach void afterEach() { System.out.println("after Each"); } }
- @disabled : 해당 테스트는 실행하지 않는다.
- @BeforeAll, @AfterAll는 모든 테스트를 실행하기 전후로 1번만 실행된다.
- @BeforeEach, @AfterEach 각 테스트를 실행하기 전후로 실행된다.
테스트 이름 표기하기
- @DisplayNameGeneration
- Method, Class레퍼런스를 사용하여 테스트 이름을 표기
- 기본 구현체로 ReplcaeUnderscores제공
- @DisplayName
- 어떤 테스트인지 테스트 이름을 보다 쉽게 표현하는 어노테이션
- @DisplayNameGeneration보다 우선 순위가 높다.
Assertion
@Test
void create_new_study() {
Study study = new Study(1);
assertNotNull(study);
assertEquals(StudyStatus.DRAFT, study.getStudyStatus(), "스터디를 처음 만들면 상태값이 DRAFT여야 한다.");
assertTrue(study.getLimit() > 0, () -> "스터디 최대 참석 인원은 0보다 커야 합니다.");
assertAll(
() -> assertNotNull(study),
() -> assertTrue(study.getLimit() > -1)
);
assertTimeout(Duration.ofMillis(100), () -> {
new Study(10);
Thread.sleep(300);
}, "테스트가 100ms 안에 끝나야합니다.");
}
- assertEquals에서 첫번째 인자는 기대하는 값, 두번째 인자는 실제값, 세번째 인자는 테스트가 실패했을때 출력되는 메세지.
- 3번째 인자로 String을 줄수도 있고, Supplier를 넣을 수도 있다.
- assertAll으로 테스트를 한번에 실행시킬 수도 있다. 이렇게 하는 이유는 위의 테스트에서 첫번째 테스트가 깨지면 밑에 테스트는 깨졌는지 안깨졌는지 조차 알 수 없다. assertAll()을 이용하면 모든 테스트를 실행하기 때문에 어떤 테스트가 깨지는지 다 알 수 있다.
- assertThrow : 예외가 발생하는지 체크
- assertTimeout : 특정시간안에 끝나는지 확인
특정 환경에서 실행시키기
@Test
@DisplayName("특정 조건에서 테스트 실행하기")
void create_study() {
String test_env = System.getenv("TEST_ENV");
assumeTrue("JIMMY".equalsIgnoreCase(System.getenv("TEST_ENV"))); // LOCAL환경에서만 테스트를 실행
assumingThat("JIMMY".equalsIgnoreCase(test_env), () -> {
Study actual = new Study(10);
assertThat(actual.getLimit()).isGreaterThan(0);
});
}
@Test
@DisplayName("어노테이션으로 테스트 조건 걸기")
@DisabledOnOs(OS.MAC)
void test() {
System.out.println("맥에서는 실행안한다.");
}
@Test
@DisplayName("어노테이션으로 테스트 조건 걸기")
@EnabledOnOs({OS.MAC, OS.LINUX})
void test2() {
System.out.println("맥에서는 실행안한다.");
}
- env는 .zshrc에 설정한 key=value
- assumingThat을 통해 특정조건에 대해서만 테스트를 실행시킬 수 있다.
- @EnabledOnOs, @DisabledOnOs, @EnabledOnJre, @EnabledIfEnvironmentVariable 등의 어노테이션을 통해 특정조건에 대해서 테스트를 돌릴 수 있다.
Taging
@Test
@DisplayName("fast 태그")
@Tag("fast")
void fast_test() {
System.out.println("fast test");
}
@Test
@DisplayName("slow 태그")
@Tag("slow")
void slow_test() {
System.out.println("slow test");
}
- 태그에 따라서 테스트 실행 유무를 나눌수도 있다. 빌드, ci환경에서 실행하는 테스트와 로컬에서 실행하는 테스트를 나눌 수 있다.
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>fast</groups>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>ci</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>fast | slow</groups>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
- profile을 설정하여 profile별로 테스트 실행하는 방법을 나눌수도 있다.
커스텀태그
-
여러개의 태그들을 조합해서 커스텀 어노테이션을 만들 수도 있다.
-
// 커스텀 어노테이션 정의 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Test @Tag("fast") public @interface FastTest { } // 테스트 코드 @FastTest @DisplayName("커스텀 어노테이션") void custom_tag() { System.out.println("커스텀 어노테이션"); }
-
느낀점
- Junit을 그냥 써왔는데, 항상 쓰는 @Test, @BeforeAll, @AfterAll, @Before, @After 어노테이션들만 사용했었다. 강의를 들으면서 다양한 Junit기능들에 대해서 알 수 있었다. Junit 책이 있으면 자세히 한번 봐야겠다… 그동안 너무 몰랐다.
Written on December 5, 2020