ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @ParameterizedTest
    ☕️ java 2023. 10. 25. 01:19

     

     

    Test 코드를 작성하는 도중 실패 케이스마다 실패 테스트 메서드를 만들다보니 중복되는 코드도 많아지고 이로 인해 코드의 양이 많아지는 문제가 발생했다.

    이런 문제를 해결하기 위해 @ParameterizedTest 를 사용해 해결하고자 알아보게 되었다.

     

    📌 Parameterized Test


    💡 Parameterized Test
    - 다른 인수로 여러번 테스트를 실행하는 것을 가능하게 한다.
    - @Test 대신 @ParameterizedTest 를 사용한다.
    - 최소 하나의 source 어노테이션을 붙여주어야 한다.

     

    💡 다양한 Source 종류들

     

    1️⃣ ValueSource

    @ParameterizedTest
    @ValueSource(strings = {"beomsic", "beom"})
    void valueSourceTest(String name) {
            
    }
    • argument가 하나인 테스트에 사용
    • short, byte, int, long, float, double, char, boolean, String, java.lang.Class 타입 지원

     

     

    2️⃣ NullSource, EmptySource, NullAndEmptySource

    @ParameterizedTest
    @ParameterizedTest
    @NullAndEmptySource
    void nullAndEmptySourceTest(List<Integer> list) {
        System.out.println(list);
    }

    결과

     

     

    NullSource   null을 보낸다
    EmptySource 비어있는 배열, 컬렉션, 문자열 등을 반환
    NullAndEmptySource NullSource와 EmptySource를 합쳐 놓은 것

     

     

    3️⃣ EnumSource

    @ParameterizedTest
    @EnumSource
    void enumSourceTest(TestEnum testEnum) {
    }
    
    public enum TestEnum {
        BEOMSIC,
        BEOM;
    }

    결과

     

     

    4️⃣ MethodSource

    @ParameterizedTest()
    @MethodSource("InputStringStream")
    void calculate_Success(String inputString, int strikeCount, int ballCount) {
         ...
    }
    
    static Stream<Arguments> InputStringStream() {
        return Stream.of(
                Arguments.of("123", 3, 0),
        );
    }
    • 테스트 클래스 내의 메소드 혹은 외부 클래스의 메소드가 반환하는 값을 source로 삼는다.
    • 테스트 클래스 내에 있고 @TestInstance(Lifecycle.PRE_CLASS)를 붙인 것이 아니라면 모두 static 메소드여야 한다.
    • 한 파라미터뿐 아니라 여러 파라미터도 넣을 수 있다.
      • 파라미터를 한 개만 넘기려면 Stream을 반환
      • 파라미터를 여러개 넘기려면 Stream<Arguments>를 반환

     

     

    5️⃣ CsvSource

    @ParameterizedTest
    @CsvSource({
      "apple,    1",
      "banana,   2"
    })
    void csvSourceTest(String fruit, int number) {
    
    }
    • , 로 분리된 문자열을 테스트 메소드의 파라미터로 넣어준다.

     

    🧑🏻‍💻 사용해보기


    👀 기존에 내가 했던 테스트 코드

    @Test
    void generateNumber_InvalidInputStringMoreThanLimitSize_ThrownException() {
        // given
        // when
        // then
        Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber("1234"))
                .isInstanceOf(IllegalArgumentException.class);
    }
    
    @Test
    void generateNumber_InvalidInputStringWithAlpha_ThrownException() {
        // given
        // when
        // then
        Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber("abc"))
                .isInstanceOf(IllegalArgumentException.class);
    }
    
    ...

     

    🔥 @ParameterizedTest를 적용한 테스트 코드

    @ParameterizedTest(name = "{0} 실패, 값 : {1}")
    @MethodSource("inValidNumberArray")
    void generateNumber_InvalidInputString_ThrownException(String reason, String inputNumber) {
        // given
        // when
        // then
        Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber(inputNumber))
                .isInstanceOf(IllegalArgumentException.class);
    }
    
    static Stream<Arguments> inValidNumberArray() {
         return Stream.of(
                Arguments.of("3자리보다 큰 숫자 문자열이 들어온 경우", "1234"),
                Arguments.of("3자리보다 작은 숫자 문자열이 들어온 경우", "12"),
                Arguments.of("영어 소문자가 포함된 경우", "a12"),
                Arguments.of("영어 소문자로만 이루어진 경우", "abc"),
                Arguments.of("한글로만 이루어진 경우", "테스트"),
                Arguments.of("특수문자가 포함된 경우", "~!@")
        );
    }

     

    📖 참고자료

    Guide to JUnit 5 Parameterized Tests | Baeldung

    JUnit 5 User Guide

    '☕️ java' 카테고리의 다른 글

    ☕️ Java 17  (1) 2023.10.25
    🆚 AssertJ과 JUnit 의 Assertions 비교  (1) 2023.10.25
    👀 Unit Test 네이밍 컨벤션  (0) 2023.10.24
    일급 컬렉션  (1) 2023.10.24
    🧪 JMH (Java Microbenchmark Harness)  (1) 2023.10.23

    댓글

Designed by Tistory.