JUnit 5 테스트를 반복해서 돌리는 방법

Chori·2021년 11월 11일
1

JUnit 5

목록 보기
5/6
post-thumbnail

테스트 메서드를 내가 원하는 만큼 반복시키는 어노테이션이 있다.
코드의 성능검증을 위해 사용해 볼 수 있는 코드 같다.

테스트를 반복시키는 방법으로 크게 두가지 방법이 있다.
@RepeatedTest 어노테이션 활용과 @ParameterizedTest 어노테이션이다.

@RepeatedTest

RepeatedTest는 설정한 인자값만큼 테스트메소드를 반복한다.

@DisplayName("반목문 테스트1")
@RepeatedTest(value = 10, name = "{displayName}, {currentRepetition}/{totalRepetitions}") //value=반복횟수, name=테스트명
void repeatedTest(RepetitionInfo repetitionInfo) { //repetitionInfo 인자를 통해 몇번째 반복되고 있는지 확인 할 수 있다.
	System.out.println("test" + repetitionInfo.getCurrentRepetition() + "/" + repetitionInfo.getTotalRepetitions());
}

RepetitionInfo를 매개변수로 지정하여 테스트 별로 반복되는 순서를 확인 할 수 있다.


@ParameterizedTest

@DisplayName("반목문 테스트2")
@ParameterizedTest(name = "{index} {displayName} message={0}") //매개변수(파라미터)를 index(0,1,2)로 참조할 수 있다.
@ValueSource(strings = {"반복문","테스트"})
void parameterizedTest(String massage) {
	System.out.println(massage);
}

@DisplayName("반목문 테스트3")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@ValueSource(ints = {10, 20, 40})
void parameterizedTest2(Integer limit) {
	System.out.println(limit);
}

ParameterizedTest는 위 코드처럼 테스트할 인자 값을 ValueSource에 지정하여 테스트 할 수 있다.
@ParameterizedTest 어노테이션에는 name으로 각각 테스트 명을 지정할 수도 있다.

테스트1은 String형 반복문 테스트이고, 테스트2는 int형 반복문 테스트다.

@CsvSource (중요)

ParameterizedTest에는 @CsvSource 어노테이션을 사용할 수 있는데,
여러인자를 콤마(,)로 구분하여 메서드에 파라미터로 넘겨줄 수 있다.

@DisplayName("반목문 테스트4")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@CsvSource({"10, '자바 스터디'", "20, '스프링'"}) //여러 인자를 콤마로 구분해서 파라미터로 넘겨줄 수 있다.
void parameterizedTest3(@ConvertWith(StudyConverter.class) Study study) {	//여러 파라미터들을 반복 테스트할 수 있는 방법  / 내가 만든 타입으로 매개변수를 만들어 인자를 받을 수 있다.
	System.out.println(study.getLimit());
}

위에는 @CsvSource를 사용해 만든 메서드이다.
인자값을 콤마(,)로 구분해 값을 넘겨주는데, 기본 타입으로만 받는 것이 아니라 커스텀 타입을 만들어 값을 받아올 수 있다.
커스텀 타입 Class파일을 아래에 기록한다.

class Study {
	private StudyStatus status = StudyStatus.DRAFT; //기본값 설정
	private int limit;
	private String name;
	
	public Study(int limit, String name) {
		this.limit = limit;
		this.name = name;
	}
	public Study(int limit) {
		if (limit < 0) {
			throw new IllegalArgumentException("limit은 0보다 커야 한다.");
		}
		this.limit = limit;
	}
	public StudyStatus getStatus() {
		return this.status;
	}
	public int getLimit() {
		return limit;
	}
	public String getName() {
		return name;
	}
}

만든 타입의 값으로 인자를 받으려면 명시적인 타입 변환이 필요하다.
StudyConverter라는 내부 class를 만들고 SimpleArgumentConverter를 상속받는다.
그리고 junit에서 제공하는 @ConvertWith어노테이션을 사용해 Study클래스의 타입을 변환할 수 있다.

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

ArgumentsAccessor, 커스텀 Accessor

여러개의 인자 값을 조합하여 테스트를 하는 방법이 있다.
ArgumentsAccessor를 활용해 인자 값을 get 할 수 있다.

@DisplayName("반목문 테스트5-1")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@CsvSource({"10, '자바 스터디'", "20, '스프링'"})
void parameterizedTest4(ArgumentsAccessor argumentsAccessor) { //여러개의 인자값들을 받아 조합해서 만든 인스턴스를 테스트 할 수 있다.
	Study study = new Study(argumentsAccessor.getInteger(0), argumentsAccessor.getString(1));
	System.out.println(study);
}

결과물
Study{state=null, limit=20, name='스프링'}

이 코드에서 매서드 내 생성자를 만들지 않고 조합된 값을 가져오고 싶다면,
커스텀 Accessor를 만들어 사용하면 된다.

@DisplayName("반목문 테스트5-2")
@ParameterizedTest(name = "{index} {displayName} message={0}")
@CsvSource({"10, '자바 스터디'", "20, '스프링'"})
void parameterizedTest5(@AggregateWith(StudyAggregator.class) Study study) { //StudyAggregator메서드를 사용하려면 @AggregateWith 어노테이션을 사용한다.
	System.out.println(study);
}

//인스턴스를 만들지 않고 커스텀 메서드를 만들어 사용하려면.
static class StudyAggregator implements ArgumentsAggregator { //제약조건 : 반드시 static inner class거나 Public class 여야 한다.
	@Override
	public Object aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) {
		return new Study(accessor.getInteger(0), accessor.getString(1)); //0번째 값의 int형 값과, 1번째 값의 String형의 값을 조합하여 리턴한다.
	} 
}

@EmptySource, @NullSource, @NullAndEmptySource

@EmptySource //비어있는 문자열의 인자를 하나 더 추가한다.
@NullSource //Null의 인자를 하나 더 추가해준다.
@NullAndEmptySource //Null과 비어있는 문자열을 하나 씩 추가한다.

@ParameterizedTest에 위 어노테이션들을 추가하여 사용할 수 있다.
테스트 마지막 부분에 비어있는 문자열이나 Null값을 추가한 테스트를 진행 할 수 있다.


본 글는 백기선님의 더 자바, 애플리케이션을 테스트하는 다양한 방법을 수강하며 학습한 내용입니다.

profile
꾸준한 성장

1개의 댓글

comment-user-thumbnail
2021년 11월 11일

좋은글 감사합니다.

답글 달기