section05부분의 Custom Annotation 부분은 미완성된 @LifeCycle이 존재하여 계속해서 수정할 예정
환경설정
앞의 Java 버전 설명을 통해 나는 11 버전을 사용하고 싶었지만 여러 상황을 고려하여 17의 버전을 사용하였다.
Java 17버전을 사용하기위해 adoptium jdk17을 설치한다
Mac OS를 사용하기 때문에 그에 맞는 설정을 진행한다
[참고자료] https://wook-lab.tistory.com/21
JUnit이란?
Java Programing 언어용 유닛 테스트 프레임워크
테스트의 결과는 test 클래스로 개발자에게 테스트의 방법과 클래스의 History를 공유 가능
단정(assert) 메서드로 테스트 케이스의 수행 결과를 판별
어노테이션으로 간결하게 지원(JUnit4부터)
section01.test
목표 : JUnit5의 기본 어노테이션 사용
JUnit5는 세 개의 서브 프로젝트로 이루어져 있다.
1. Junit Platform
- JVM에서 테스트 프레임워크를 실행하기 위한 테스트 엔진을 제공한다.
2. Junit Jupiter
- Junit5에서 테스트를 작성하고 실행하기 위한 엔진을 제공한다.
3. Junit Vintage
- Junit3, 4를 기반으로 돌아가는 테스트 엔진을 제공해준다 (하휘 호환용)
테스트 클래스의 경우 한 개 이상의 @Test 어노테이션이 필요하며 한 개 이상의 생성자를 가지고있다.
기본 어노테이션을 사용하기 위한 코드
@Test
@DisplayName("테스트 메서드 1")
public void testMethod1() {
}
// @DisplayName어노테이션을 통해 설정한 이름 값으로 Test결과를 표기해준다.
@Test
@DisplayName("displayName 우선순위 테스트")
public void 테스트_메서드2() {
// @DisplayName과 중복 작성 시에는 @DisplayName에 부여한 테스트 이름이 우선권을 가진다.
}
section02.test
목표 : 테스트 메서드의 실행 전 후에 동작하는 어노테이션을 활용
테스트가 실행되기 전 한 번만 실행되는 어노테이션
@BeforeAll
public static void beforeAll() {
System.out.println("beforeAll")
// 각각의 테스트 메서드가 실행되기 전 실행되나
// @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 실행되기 전에 동작한다.
// 주로 테스트 하기 전에 필요한 목업 데이터를 미리 세팅해줄 목적으로 사용된다.
// 각각의 테스트 메서드가 동작한 직후 동작을 한다.
// @Test, @RepeatedTest, @ParameterizedTest, @TestFactory가 실행된 이후 동작한다..
// 주로 단위 테스트들이 수행된 이후 사용한 자원을 해제할 목적으로 사용한다.
@AfterEach
public void afterEach() {
System.out.println("afterEach");
}
// 모든 단위테스트가 완전히 끝난 후 딱 한 번만 실행된다.
@AfterAll
public static void afterAll() {
System.out.println("afterAll");
}
section3.test
목표 : JUnit에서 제공하는 테스트 관련 추가 어노테이션을 사용
테스트를 무시하기 위한 어노테이션
// 해당 테스트를 무시할 때 사용하는 어노테이션이다.
// Junit4에서는 @Ignore와 동일한 기능으로 사용된다.
@Disabled
@Test
public void testIgnore() {
}
// 주어진 시간 안에 테스트가 끝나지 않으면 테스트가 실패한다.
// value에는 시간을 정수형으로, unit 사용할 시간 단위를 기술한다.
@Test
@Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
public void testTimeout() throws InterruptedException{
Thread.sleep(900);
}
// Thread.sleep(1000)을 초과하면 에러를 발생시킨다.

@Tag 어노테이션
// @Tag 태그를 이용하여 테스트를 필터링 할 수 있다.
// @Tag를 사용하기 위한 규칙
// 1. 태그는 공백이나 null이 있으면 안된다.
// 2. 다음 글자들은 포함하면 안된다 -> : . ( ) & ! |
@Test
@Tag("development")
public void testTag1() {
}
@Test
@Tag("production")
public void testTag2() {
}
@Test
@Tags(value = {@Tag("development"), @Tag("production")})
public void testTag3() {
}
// 태그의 값에 따라 테스트 코드가 출력되거나 생략된다.
// 테스트 메서드는 실행 순서가 보장되지 않지만 경우에 따라서는 (통합테스트 환경 등 ) 테스트의 순서가 중요한 경우도 있다.
// 클래스 레벨에 @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 어노테이션을 추가하고
// 각 테스트 메서드에 @Order 어노테이션으로 순서를 지정하면 테스트 순서를 설정할 수 있다.
// 클래스에 작성한 테스트 메서드의 순서는 MethodOrderer에 DisplayName, MethodName, OrderAnnotation, Random 등이 있다.
@Test
@Order(1)
public void testFirst() {}
@Test
@Order(2)
public void testSecond() {}
@Test
@Order(3)
public void testThird() {}
section04.test
수업목표 : 운영체제, JRE에 따라 테스트를 수행
테스트 메서드는 특정 OS 환경에서만 테스트를 진행되게 할 수 있다.
이 때, 특정 OS에서 무시되는 사유를 disabledReason에 기술하여
테스트 코드가 무시되는 사유를 다른 사람도 함께 알 수 있게 한다.
@EnabledOnOs 어노테이션
@Test
@EnabledOnOs(value = OS.MAC, disabledReason = "맥에서만 테스트합니다.")
public void testMAC() {}
@Test
@EnabledOnOs(value = {OS.WINDOWS, OS.LINUX}, disabledReason = "윈도우와 리눅스만 테스트합니다.")
public void testWindowsAndLinux() {}
@Test
@DisabledOnOs(value = OS.WINDOWS, disabledReason = "윈도우 환경에서는 테스트를 무시합니다.")
public void testDisabledOnWindows() {}
// 각각의 환경에 맞게 Mac의 경우, Windows의 경우에 맞게 테스트 실행
// @EnableOnJre를 이용하여 특정 JRE 버전에서만 테스트 하는 것도 가능하다.
// @DisabledOnJre를 이용하여 특정 JRE 버전에서만 테스트를 Disabled하는 것도 가능하다.
// @EnableForJreRange를 이용하면 min과 max 속성 사이의 버전에서 테스트 하는 것도 가능하다.
// (min만 작성시 min~최신버전까지, max만 작성 시 이전 버전부터 max까지만 테스트를 한다.)
@Test
@EnabledOnJre(value = JRE.JAVA_8, disabledReason = "JRE 1.8. 환경에서만 테스트합니다.")
public void testJRE() {}
@Test
@EnabledOnJre(value = {JRE.JAVA_8, JRE.JAVA_17})
public void testJRE8ANDJRE17() {}
@Test
@DisabledOnJre(value = JRE.JAVA_17)
public void testDisabledJRE17() {}
@Test
@EnabledForJreRange(min = JRE.JAVA_8, max = JRE.JAVA_17)
public void testFromJRE8TOJRE17() {}
section05.test
목표 : 원하는 어노테이션을 조합하여 커스텀 어노테이션을 생성 및 사용
@MacTest 어노테이션 생성
// 생성된 어노테이션의 활용
@MacTest
public void testOnMacOS() {}
//MacTest 어노테이션을 생성하기위한 어노테이션 인터페이스 파일
@Retention(RetentionPolicy.RUNTIME)
// Retention -> 어노테이션이 언제까지 유지될지 명시하는 것
@Target(ElementType.METHOD)
// Target -> 이 어노테이션에 적용될 수 있는 JAVA 요소의 종류를 지정
@EnabledOnOs(value = OS.MAC, disabledReason = "맥 환경에서는 작동하지 않습니다.")
@Test
public @interface MacTest {
}
// 생성된 어노테이션 활용
@DevelopmentTest
public void testDevelopmentCustomTag() {}
//DevelopmentTest 어노테이션을 생성하기 위한 어노테이션 인터페이스 파일
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Tag("development")
@Test
public @interface DevelopmentTest {
}
// 생성된 어노테이션 활용
@TimeTest
public void testTime() throws InterruptedException{
Thread.sleep(100);
}
//TimeTest 어노테이션을 생성하기 위한 어노테이션 인터페이스 파일
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Timeout(value = 1000, unit = TimeUnit.MILLISECONDS)
@Test
public @interface TimeTest {
}
//생성된 어노테이션 활용
@LifeCycle
public void testLifeCycle() {
}
// LifeCycle 어노테이션을 생성하기 위한 어노테이션 인터페이스 파일
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Test
@BeforeAll
@AfterEach
@AfterAll
public @interface LifeCycle {
}
가장 먼저 이런 식으로 작성 후 테스트를 실행했는데,
org.junit.platform.commons.JUnitException: @BeforeAll method 'public void com.ohgiraffers.section05.custom.CustomAnnotationTests.testLifeCycle()' must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).
이러한 경고 메세지가 발생하였다.
"@BeforeAll, @AfterAll의 경우 static으로 선언을 하여야한다"라는 에러가 출력되었다.
이를 해결하기 위해 테스트 클래스 안에 각각 어노테이션을 선언하고 함수를 지정한 후 @LifeCycle어노테이션을 사용하는 메서드인 testLifeCycle() 내에 선언한 함수들을 실행시켜보았다.
@LifeCycle
public void testLifeCycle() {
testbefore();
test1();
test2();
afterEach();
afterAll();
}
@BeforeAll
public static void testbefore() {
System.out.println("beforeAll");
}
public void test1() {
System.out.println("test1");
}
public void test2() {
System.out.println("test2");
}
@AfterEach
public void afterEach() {
System.out.println("afterEach");
}
@AfterAll
public static void afterAll() {
System.out.println("afterAll");
}
Class Configuration라는 에러가 발생하였고, org.junit.platform.commons.JUnitException: @BeforeAll method 'public void com.ohgiraffers.section05.custom.CustomAnnotationTests.testLifeCycle()' must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS)라고 출력되었다.
수정하여도 같은 에러가 발생하였고, 또 다른 방법으로 수정해보기 위해 LifeCycle 어노테이션 인터페이스를 수정하였다.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Test
public @interface LifeCycle {
}
LifeCycle 어노테이션 인터페이스를 수정 후 내가 원하는 방향으로 약간의 결과가 출력되었긴 했지만 LifeCycle 어노테이션을 통해서 출력된 것이 아니라고 생각되었다.
완벽하게 수정하여 다시 이 곳에 작성할 예정이다.