기본 annotation 테스트

package hello.test;

import org.junit.jupiter.api.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class StudyTest {

    @Test
     @DisplayName("학생 생성 테스트") //테스트 이름 정의
     void create() {
        Study  study = new Study();
        assertNotNull(study);
        System.out.println("create1");
        assertEquals(StudyStatus.NOTHING, study.getStatus(),"초기상태 WATING");
                                 //기대값                  //현재 상태
        assertEquals(StudyStatus.NOTHING, study.getStatus(), () -> "초기값은 NOTHING 이어야 합니다.");
         //lambda 식으로 변경(lambda로 변경하는 경우 해당 수행이 실패하는 경우에만 message연산을 수행
        
        assertAll(
                () -> assertNotNull(study),
                () -> assertEquals(StudyStatus.NOTHING, study.getStatus(), () -> "초기값은 NOTHING 이어야 합니다."),
                () -> assertTrue(study.getLimit() > 0, () -> "최대 참석인원은 0 명보다 커야합니다.")
        ); //람다식으로 3개의 assert문 실행결과 확인 가능 
    }

    @Test
    @Disabled  //전체 클래스 테스트 수행시 동작하지 않도록 정의
    void create2() {
         IllegalArgumentException exception =  assertThrows(IllegalArgumentException.class, ()-> new Study(-1));
        assertEquals("Limit은 0보다 커야함.",exception.getMessage());
        //해당 excpetion의 message가 기대하는 값과 같은지 확인
    }

    @Test
    @DisplayName("생성 timeout 확인")
    void create3() {
        assertTimeout(Duration.ofSeconds(1), () -> new Study());
        //1초안에 생성자 생성
        
        assertTimeout(Duration.ofMillis(100), () -> {
            new Study();
            Thread.sleep(30000);
        }); // 30000 millisecond 이후에 실패 처리

        assertTimeoutPreemptively(Duration.ofMillis(100), () -> {
            new Study();
            Thread.sleep(3000);
        }); // 100 millisecond가 지나면 바로 실패 처리
    }
    
     @Test
    void create4() {
        Study actual = new Study(10);
        assertThat(actual.getLimit()).isGreaterThan(0);  //3rd party assertjs
    }

    @BeforeAll  //테스트를 실행하기 전에 딱 1번 반드시 static 메소드로만 사용가능. 리턴타입 없음.
    static void BeforeAll() {
        System.out.println("BeforeALL");
    }

    @AfterAll  // 테스트를 실행한 이후 딱 1번만 수행(반드시 static 메소드로만 사용가능. 리턴타입 없음
    static void AfterAll() {  //모든 테스트가 실행된 이후에 1번만 실행
        System.out.println("AfterAll");
    }

    @BeforeEach //각 테스트 수행 전 1번 실행
    void BeforeEach() {
        System.out.println("BeforeEach");
    }

    @AfterEach // 각 테스트 수행 후 1번 실행
    void AfterEach() {
        System.out.println("AfterEach");
    }
}

 

condition에 따라서 테스트 실행

import org.junit.jupiter.api.*;

import java.time.Duration;
import java.util.function.Supplier;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.assumeTrue;


....

    @Test
    void conditionTest() {
        assumeTrue("LOCAL".equalsIgnoreCase(System.getenv("TEST_ENV")));
        //TEST_ENV라는 환경변수가 LOCAL인 경우에만 아래 테스트가 수행됨.
        Study study = new Study();
        assertNotNull(study);
    }
    
    @Test
    void conditionTest2() {
        String env = System.getenv("TEST_ENV");
        //TEST_ENV라는 환경변수가 LOCAL인 경우에만 아래 테스트가 수행됨.
        assumingThat(("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println("succeed to test");
        });
        //TEST_ENV라는 환경변수가 LOCAL가 아닌 경우에만 아래 테스트가 수행됨.
        assumingThat(!("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println("Failed to test");
        });

        Study study = new Study();
        assertNotNull(study);
    }
    
     @Test
    @EnabledOnOs(OS.WINDOWS)  //특정 OS에 특화된 테스트시 활용
    @EnabledOnJre(JRE.JAVA_11) //자바 11버전에서만 실행
    @EnabledIfEnvironmentVariable(named= "TEST_ENV", matches = "local") //환경변수 TEST_ENV가 local인 경우에만 실행
    void conditionTest3() {
        String env = System.getenv("TEST_ENV");
        //TEST_ENV라는 환경변수가 LOCAL인 경우에만 아래 테스트가 수행됨.
        assumingThat(("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println(env);
        });
        //TEST_ENV라는 환경변수가 LOCAL가 아닌 경우에만 아래 테스트가 수행됨.
        assumingThat(!("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println(env);
        });

        Study study = new Study();
        assertNotNull(study);
    }

 

 

커스텀 테그

package hello.test;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Test
@Tag("slow")
public @interface SlowTest {
}

...........




//실제 사용 Test
    @SlowTest
    void conditionTest() {
        String env = System.getenv("TEST_ENV");
        assumeTrue("LOCAL".equalsIgnoreCase(env));
        //TEST_ENV라는 환경변수가 LOCAL인 경우에만 아래 테스트가 수행됨.
        assumingThat(("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println("succeed to test");
        });
        assumingThat(!("LOCAL".equalsIgnoreCase(env)),()->{
            System.out.println("succeed to test");
        });

        Study study = new Study();
        assertNotNull(study);
    }

 

 

테스트 반복 실행

package hello.test;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.aggregator.AggregateWith;
import org.junit.jupiter.params.aggregator.ArgumentsAccessor;
import org.junit.jupiter.params.aggregator.ArgumentsAggregationException;
import org.junit.jupiter.params.aggregator.ArgumentsAggregator;
import org.junit.jupiter.params.converter.ArgumentConversionException;
import org.junit.jupiter.params.converter.ConvertWith;
import org.junit.jupiter.params.converter.SimpleArgumentConverter;
import org.junit.jupiter.params.provider.*;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class OtherTest {
    @RepeatedTest(10)
    @DisplayName("반복 테스트1")
    public void test1() {
        System.out.println("repeat test");
    }

    @DisplayName("반복 테스트 2")
    @RepeatedTest(value = 10, name= "{displayName},{currentRepetition}/{totalRepetitions}")
    public void ParameterizedTest1(RepetitionInfo repetitionInfo) {
        System.out.println("count:"+ repetitionInfo.getCurrentRepetition() +"total:"
        + repetitionInfo.getTotalRepetitions());
    }

    @DisplayName("파라미터 출력")
    @ParameterizedTest(name = "{index} {displayName} message={0}")
    @ValueSource(strings = {"1","2","3","4"})
    @EmptySource
    @NullSource
    @NullAndEmptySource //empty와 null을 동시에 파라미터로 넘김
    void ParameterizedTest2(String str) {
        System.out.println(str);
    }

    @DisplayName("파라미터 출력1")
    @ParameterizedTest(name = "{index} {displayName} message={0}")
    @ValueSource(ints ={10, 20, 30})
    void ParameterizedTest3(@ConvertWith(ArgumentConvert.class) Study study) {
        System.out.println(study.getLimit());
    }

    @DisplayName("파라미터 출력2")
    @ParameterizedTest(name = "{index} {displayName} message={0}")
    @CsvSource({"10, '자바 테스트1'" ,"20, '파이썬 테스트1'"})
    void ParameterizedTest4(Integer limit, String name) {
        System.out.println(new Study(limit,name));
    }


    static class ArgumentConvert extends SimpleArgumentConverter { //1개의 argument에 사용
        @Override
        protected Object convert(Object source, Class<?> targetType) throws ArgumentConversionException {
            assertEquals(Study.class, targetType,"can only covert to Study" );
            return new Study(Integer.parseInt(source.toString()));
        }
    }

    @DisplayName("파라미터 출력3")
    @ParameterizedTest(name = "{index} {displayName} message={0}")
    @CsvSource({"30, '자바 테스트2'" ,"40, '파이썬 테스트2'"})
    void ParameterizedTest5(ArgumentsAccessor argumentsAccessor) {
        System.out.println(new Study(argumentsAccessor.getInteger(0),argumentsAccessor.getString(1)));
    }

    @DisplayName("파라미터 출력4")
    @ParameterizedTest(name = "{index} {displayName} message={0}")
    @CsvSource({"50, '자바 테스트3'", "60, '파이썬 테스트3'"})
    void ParameterizedTest6(@AggregateWith(Aggregator.class) Study study) {
        System.out.println(study.getLimit()+" "+ study.getName());
        System.out.println(study);
    }

     static class Aggregator implements ArgumentsAggregator {
        @Override
        public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) throws ArgumentsAggregationException {
            Study study = new Study(accessor.getInteger(0),accessor.getString(1));
            return study;
        }
    }
}

 

 

테스트 인스턴스

package hello.test;

import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;

//@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
//@TestInstance(TestInstance.Lifecycle.PER_CLASS)  //테스트클래스의 테스트메소드간 인스턴스 공유
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)  //테스트 순서 지정
//@ExtendWith(TestExtension.class) // extension 을 선언적으로 등록하는 방법
public class InstanceTest {

    int value = 1;

    @RegisterExtension //extension 을 프로그래밍하여 등록하는 방법
    static TestExtension testExtension = new TestExtension(500L);

    @DisplayName("인스턴스 테스트")
    @Test
    @Order(2) //2번째로 실행
    void instance_Test1() {
        System.out.println("instance test1:" + value++);
    }

    @DisplayName("인스턴스 테스트")
    @Test
    @Order(1) //첫번째로 실행
    @Disabled
    void instance_Test2() {
        System.out.println("instance test2:" + value++);
    }

    @Test
    @Order(3) //세번째로 실행
    void instance_Test3() {
        System.out.println("instance test3:" + value);
    }

    @BeforeAll
    void beforeAll() {
        System.out.println("beforeAll");
    }

    @AfterAll
    void afterAll() {
        System.out.println("afterAll");
    }

    @Test
    void create_new() {
        try {
            Thread.sleep(1005L);
            System.out.println(this);
            System.out.println("test");
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

 

Extension 클래스

package hello.test;

import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

import java.lang.reflect.Method;

public class TestExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    private long THRESHOLD;

    public TestExtension(long THRESHOLD) {
        this.THRESHOLD = THRESHOLD;
    }

    @Override
    public void beforeTestExecution(ExtensionContext context) throws Exception {
        ExtensionContext.Store store = getStore(context);
        store.put("startTime", System.currentTimeMillis());
    }

    @Override
    public void afterTestExecution(ExtensionContext context) throws Exception {
        Method requiredTestMethod = context.getRequiredTestMethod();
        SlowTest annotation = requiredTestMethod.getAnnotation(SlowTest.class);
        String testMethodName = requiredTestMethod.getName();
        ExtensionContext.Store store = getStore(context);
        long start_time = store.remove("startTime", long.class);
        long duration = System.currentTimeMillis() - start_time;
        if (duration > THRESHOLD && annotation == null) {
            System.out.printf("please consider mark method [%s] with @SlowTest.\n", testMethodName);
        }
    }

    private ExtensionContext.Store getStore(ExtensionContext context) {
        String testClassName = context.getRequiredTestClass().getName();
        String testMethodName = context.getRequiredTestMethod().getName();
        ExtensionContext.Store store = context.getStore(ExtensionContext.Namespace.create(testClassName, testMethodName));
        return store;
    }
}

' > JUnit5' 카테고리의 다른 글

JUnit5  (0) 2022.02.27

+ Recent posts