본문 바로가기
Java

[Java] JUnit 5 사용법 (7) - 테스트 순서 (@TestMethodOrder)

by 노력남자 2022. 9. 6.
반응형

이번 시간엔 JUnit 5 의 테스트 간 순서를 정하는 방법에 대해 알아보겠습니다.

 

JUnit 5의 테스트 순서

 

@TestMethodOrder에 쓰여져있는 주석으로 설명드리겠습니다.

 

"@TestMethodOrder가 선언되어있지 않다면 기본 알고리즘에 의해 순서가 정해지지만 아닌 경우도 있다". 라고 써져있습니다.

 

 * <p>If {@code @TestMethodOrder} is not explicitly declared on a test class,
 * inherited from a parent class, or declared on a test interface implemented by
 * a test class, test methods will be ordered using a default algorithm that is
 * deterministic but intentionally nonobvious.

 

어떠한 이유로 인해 (ex. @TestInstance(value = PER_CLASS)) 테스트들의 실행 순서가 반드시 필요하다면 @TestMethodOrder을 사용해야 합니다.

 

@TestMethodOrder

 

테스트 순서를 정해주는 어노테이션

 

파라미터명 타입 설명
value Class<? extends MethodOrderer> 정렬 타입

MethodName : 메소드명
DisplayName : @DisplayName
OrderAnnotation : @Order(n) 
Random : 랜덤

 

예제

 

MethodName

 

메소드명으로 오름차순 정렬 (a~ㄱ), 메소드명이 같다면 파라미터 타입명으로 오름차순 정렬

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

@TestMethodOrder(MethodOrderer.MethodName.class)
public class MethodNameTest {

    @ParameterizedTest
    @ValueSource(ints = 1)
    void a_test(Integer s) {
    }

    @ParameterizedTest
    @ValueSource(strings = "1")
    void a_test(String s) {
    }

    @Test
    void b_test() {
    }

    @Test
    void c_test() {
    }
}

 

 

DisplayName

 

@DisplayName의 값으로 오름차순 정렬

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(value = MethodOrderer.DisplayName.class)
public class DisplayNameTest {

    @DisplayName("c_test, method : a_test")
    @Test
    void a_test() {
    }

    @DisplayName("a_test, method : b_test")
    @Test
    void b_test() {
    }

    @DisplayName("b_test, method : c_test")
    @Test
    void c_test() {
    }
}

 

 

OrderAnnotation

 

@Order(n) 어노테이션으로 순서를 정하는 방법

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.*;

@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class)
public class OrderAnnotationTest {

    @Order(3)
    @Test
    void a_test() {
    }

    @Order(2)
    @Test
    void b_test() {
    }

    @Order(1)
    @Test
    void c_test() {
    }
}

 

 

Random

 

랜덤으로 순서를 정하는 방법

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

@TestMethodOrder(MethodOrderer.Random.class)
public class RandomTest {

    @Test
    void a_test() {
    }

    @Test
    void b_test() {
    }

    @Test
    void c_test() {
    }
}

 

1, 2회 결과

 

@TestMethodOrder 커스텀

 

이미 구현된 MethodOrderer 구현체 이외에 개발자 원하는 형태의 정렬로 구현하는 방법을 소개합니다.

 

MethodOrderer 를 implements 해서 구현하시면 됩니다.

 

예제

 

MethodName 내림차순으로 구현해보겠습니다.

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.MethodDescriptor;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.MethodOrdererContext;
import org.junit.platform.commons.util.ClassUtils;

import java.lang.reflect.Method;
import java.util.Comparator;

public class MethodNameReverse implements MethodOrderer {

    @Override
    public void orderMethods(MethodOrdererContext context) {
        context.getMethodDescriptors().sort(comparator);
    }

    private static final Comparator<MethodDescriptor> comparator = Comparator.<MethodDescriptor, String>
            comparing(descriptor -> descriptor.getMethod().getName())
            .thenComparing(descriptor -> parameterList(descriptor.getMethod())).reversed();

    private static String parameterList(Method method) {
        return ClassUtils.nullSafeToString(method.getParameterTypes());
    }
}

 

MethodNameReverse를 만든 후 @TestMethodOrder에 적용

 

package com.effortguy.junit5.testMethodOrderAnnotation;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

@TestMethodOrder(value = MethodNameReverse.class)
public class CustomTest {

    @ParameterizedTest
    @ValueSource(ints = 1)
    void a_test(Integer s) {
    }

    @ParameterizedTest
    @ValueSource(strings = "1")
    void a_test(String s) {
    }

    @Test
    void b_test() {
    }

    @Test
    void c_test() {
    }
}

 

결과

 

 

 

다음 포스팅에선 OS, JAVA, 시스템 환경변수 별 테스트에 대해서 알아보겠습니다.

 

읽어주셔서 감사합니다.

반응형

댓글