2020-12-5 백기선님 더자바 테스트(1) 강의정리 Junit

테스트 반복

@DisplayName("스터디 만들기")
@RepeatedTest(value = 5, name = "{displayName}, {currentRepetition}/{totalRepetition")
void repeat_test(RepetitionInfo repetitionInfo) {
  System.out.println("반복 테스트 " + repetitionInfo.getCurrentRepetition() + "/" + repetitionInfo.getTotalRepetitions());
}

@ParameterizedTest
@ValueSource(strings = {"날씨가", "많이", "추워지고", "있네요"})
void parameterized_test(String message) {
  System.out.println("파라미터 갯수만큼 출력 : " + message);
}
  • @RepeatedTest을 통해 반복적인 테스트를 만들 수 있다. 하지만 다른 파라미터로 테스트 하기 위해서는 @ParameterizedTest를 쓰는게 좋다.
  • @ValueSource를 이용하여 ParameterizedTest에 전달하고자 하는 인자들을 넘겨서 테스트를 할 수 있다. @EmptySource, @NullSource, @NullAndEmptySource를 이용하여 null, empty를 전달할 수도 있다.
  • @CvsSource를 이용하면 여러인자를 넘겨줄 수 있다.
@DisplayName("인자 전달 테스트")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@ValueSource(ints = {10, 20, 40})
void parameterized_test2(@ConvertWith(StudyConverter.class) Study study) {
  System.out.println("Study limit 출력 : " + study.getLimit());
}

static class StudyConverter extends SimpleArgumentConverter {
  @Override
  protected Object convert(Object o, Class<?> aClass) throws ArgumentConversionException {
    assertEquals(Study.class, aClass, "Can only convert to Study class");
    return new Study(Integer.parseInt(o.toString()));
  }
}

@DisplayName("여러개의 커스텀 인자 전달 테스트")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@CsvSource({"10, '자바 스터디'", "20, 'hello study'"})
void parameterized_test3(@AggregateWith(StudyAggregator.class) Study study) {
  System.out.println(study);
}

static class StudyAggregator implements ArgumentsAggregator {
  @Override
  public Object aggregateArguments(ArgumentsAccessor argumentsAccessor, ParameterContext parameterContext) throws ArgumentsAggregationException {
    return new Study(argumentsAccessor.getInteger(0), argumentsAccessor.getString(1));
  }
}
  • CustomConverter를 통해 ValueSource를 통해 전달받은 인자들을 Converting해서 특정 클래스로 받을 수 있다.
  • ArgumentConverter는 1개의 인자에 대해서만 Converting을 하고, 여러개의 인자인 경우 Aggregator를 활용하여 Converter를 만들어야한다.
  • ArgumentAggregator 인터페이스를 확장하여 StudyAggregator라는 Converter를 만든다.
  • ArgumentAggregator는 static inner클래스이거나 public 클래스여야한다.

테스트 인스턴스

  • class StudyTest 안에 @Test가 붙은 여러개의 테스트가 존재한다고 하자. Junit은 각 Test를 실행할때마다 StudyTest를 각각 생성해서 실행한다. 테스트간의 의존성을 없애기 위해 인스턴스를 새로 만드는거다.

  • Junit5에서는 인스턴스 전략을 바꿀 수 있다. 클래스당 1개만 만들어서 공유할 수 있다. 매번 인스턴스를 안만들어서 성능적인 장점이 있다.

  • @TestInstance에서 라이프사이클을 지정할 수 있다. 이렇게 되면 @BeforeAll, @AfterAll를 정의할때 static으로 안해도 된다.

  • @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    class StudyTest {
    }
    

-

테스트 순서

  • @Test 선언 순으로 어느정도 순서대로 실행되지만 순서가 보장되지는 않는다.
  • 각각의 테스트는 독립성이 보장되어야되고 의존성이 있으면 안되지만 경우에 따라서 상태관리를 위해 순서가 필요할때도 있다.
  • @TestMethodOrder()를 통해 지정할 수 있다. 인자로는 MethodOrderer 인터페이스를 구현한 구현체를 넘겨야한다.
  • @Order(value)를 테스트메서드에 붙여서 사용한다. 값이 낮을수록 우선순위가 높다.

Junit 설정파일

  • test/resource/junit-platform.properties로 설정파일을 만든다.

  • # 테스트 인스턴스 기본 라이크 사이클 설정
    junit.jupiter.testinstance.lifecycle.default=per.class
    
    # 확장팩 자동 감지 기능
    junit.jupiter.extensions.autodetection.enabled=true
    
    # @Diabled무시하고 실행
    junit.jupiter.conditions.deactivate=org.junit.*DisabledCondition
    

    느낀점

    • @ParameterizedTest, @CsvSource와 같은 어노테이션에 대해서 전혀 알지 못했다. 그래서 매번 파라미터가 달라지는 테스트에 대해서는 하나하나 테스트코드를 수동으로 작성했었다. 간단한 방식을 이용하여 테스트를 반복수행할 수 있고, 전달되는 인자들도 Converter를 이용해서 객체형으로 받는 방법을 배웠다.
Written on December 7, 2020