-
[JUnit] JUnit 핵심 (1) 생애주기와 동작원리 / 테스트 클래스와 메서드 / 애노테이션DEV/JUnit 2024. 6. 20. 15:26
TDD 하고싶어서 학습하는 JUnit 프레임워크, 책을 기반으로 학습하고 정리하고자한다.
참고 도서
https://www.yes24.com/Product/Goods/126579542
해당 책에서는 JUnit5를 주로 다루고 JUnit4와 비교하는 부분이 있을 것으로 보인다.
샘플 코드
https://github.com/devkunst/junit-in-action-third-edition-kr
- 테스트 클래스 : 클래스, 정적 멤버 클래스, 하나 이상의 테스트 메서드를 포함하는 @Nested 애노테이션이 붙은 내부 클래스를 말한다.
- 추상 클래스일 수 없으며 단일 생성자를 가져야한다.
- 테스트 클래스의 생성자는 파라미터가 아예 없거나, 런타임 의존성 주입으로 동적으로 리졸브할 수 있는 파라미터만 사용할 수 있다.
- JUnit4와 다르게 JUnit5부터 public이 아닌 default 접근 제어자를 사용할 수 있다.
- 테스트 메서드 : @Test, @RepeatedTest, @ParameterizedTest, @TestFactory, @TestTemplate 애노테이션이 붙은 메서드를 말한다.
- 추상 메서드일 수 없으며 반환 값을 가질 수 없다. 무조건 void 타입.
- 생애주기 메서드 : @BeforeAll, @AfterAll, @BeforeEach, @AfterEach 애노테이션이 붙은 메서드를 말한다.
- @BeforeAll : 전체 테스트가 실행되기 전에 한 번 실행. 테스트 클래스에 @TestInstance(Lifecycle.PER_CLASS) 애노테이션이 없으면 static으로 선언해야한다.
- @BeforeEach : 각 테스트가 실행되기 전에 실행된다.
- @AfterAll :전체 테스트가 실행 된 후 한 번 실행. @TestInstance(Lifecycle.PER_CLASS) 애노테이션이 없으면 static으로 선언해야한다.
- @AfterEach : 각 테스트가 실행된 이후에 실행된다.
JUnit은 테스트 메서드의 격리성을 보장하고 테스트 코드에서 의도치 않은 부수효과(side effect)를 방지하기 위해
@Test 메서드를 호출하기 전에 테스트 클래스 인스턴스를 매번 새로 만든다.
테스트 메서드는 매번 새로 만들어진 테스트 클래스 인스턴스에서 실행되므로 테스트 메서드 간에 인스턴스 변수를 재사용할 수 없다.
대신 @TestInstance(Lifecycle.PER_CLASS) 애노테이션을 추가하면 JUnit5는 동일한 테스트 인스턴스를 가지고 클래스에 있는 모든 테스트 메서드를 실행한다. 테스트 클래스 인스턴스가 메서드 단위가 아닌 클래스 단위로 생성되는 것이다.
@DisplayName
package com.study.junit.ch02; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @DisplayName("Test class showing the @DisplayName annotation.") public class DisplayNameTest { private SUT systemUnderTest = new SUT(); @Test @DisplayName("Our system under test says hello.") void testHello() { assertEquals("Hello", systemUnderTest.hello()); } @Test @DisplayName("😱") void testTalking() { assertEquals("How are you?", systemUnderTest.talk()); } @Test void testBye() { assertEquals("Bye", systemUnderTest.bye()); } }
- 테스트 클래스, 테스트 메서드에 사용
- 테스트 목적을 알려줄 수 있는 완전한 문장으로 적는 것이 일반적이다.
- 공백, 특수문자, 이모지도 사용할 수 있다.
- 디스플레이 네임을 따로 명시하지 않은 테스트는 메서드 이름을 표시한다.
실행결과
책에서와는 다르게 나는 인코딩 설정을 안해줘서 그런지 물음표로 나온다 ..
이모지 쓸 일은 없을 것 같으니 패스 ..
@Disabled
package com.study.junit.ch02; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class DisabledMethodTest { private SUT systemUnderTest = new SUT("테스트 대상 시스템"); @Test @Disabled //테스트 비활성화 이유 알 수 없음 void testRegularWork() { boolean canReceiveRegularWork = systemUnderTest.canReceiveRegularWork(); assertTrue(canReceiveRegularWork); } @Test @Disabled("기능 개발 중") void testAdditionalWork() { boolean canReceiveAdditionalWork = systemUnderTest.canReceiveAdditionalWork(); assertFalse(canReceiveAdditionalWork); } }
- 테스트 클래스나 테스트 메서드에서 사용
- 해당 애노테이션을 붙이면 클래스단위나 메서드 단위로 비활성화 되어 테스트가 실행되지 않는다.
- 비활성화한 이유를 구체적으로 작성할 것을 권장한다.
'DEV > JUnit' 카테고리의 다른 글
[JUnit] 모의 객체로 테스트하기 (0) 2024.08.25 [JUnit] 스텁을 활용한 테스트 (0) 2024.07.14 [JUnit] JUnit4에서 JUnit5로 마이그레이션 (0) 2024.06.30 [JUnit] JUnit 핵심 (3) 의존성 주입 / 반복 테스트 / 파라미터 테스트 / 동적 테스트 / Hamcrest vs AssertJ (0) 2024.06.26 [JUnit] JUnit 핵심 (2) 중첩 테스트 / 태그 테스트 / 단언문 / 가정문 (2) 2024.06.20