ParameterizedTest란?
일반적으로 테스트를 실행할 때는, 함수에 대한 하나의 입력 값만 테스트하지 않는다. 예를 들어 간단한 곱샘 연산을 실행하는 Simple Multiplier가 다음과 같이 있다고 해보자.
class SimpleMultiplier() {
fun multiplyAll(vararg numbers: Int): Int {
return numbers.fold(1) { acc, number ->
acc * number
}
}
}
이 SimpleMultiplier에 대한 테스트는 다음과 같이 세가지 경우에 대해 작성될 수 있다.
1. 양의 정수 끼리 곱하는 경우
2. 양의 정수와 음의 정수를 곱하는 경우
3. 0을 포함해 곱하는 경우
class SimpleMultiplierTest {
lateinit var simpleMultiplier : SimpleMultiplier
@BeforeEach
fun setUp() {
simpleMultiplier = SimpleMultiplier()
}
@Test
fun `check_2_multiply_3_is_6`() {
// When
val result = simpleMultiplier.multiplyAll(2, 3)
// Then
assertEquals(6, result)
}
@Test
fun `check_2_multiply_-3_is_-6`() {
// When
val result = simpleMultiplier.multiplyAll(2, -3)
// Then
assertEquals(-6, result)
}
@Test
fun `check_multiplier_returns_0_if_it_contains_0`() {
// When
val result = simpleMultiplier.multiplyAll(2, 0)
// Then
assertEquals(0, result)
}
}
하지만, 이렇게 테스트 코드를 작성하면 테스트 코드가 너무 길어진다. 테스트 코드가 길어진다는 것은 가독성이 떨어진다는 뜻이며, 이는 유지 보수를 어렵게 만든다. 이렇게 다양한 종류의 입력값을 테스트하기 위해 ParameterizedTest를 사용할 수 있다. ParameterizedTest는 특정 함수를 서로 다른 변수에 대해 여러 번 실행하기 위해 사용된다.
ParameterizedTest를 진행하기 위한 환경 설정
JUnit4에서는 기본 의존성을 설정하는 것만으로 Parameterized 테스트가 가능했지만, JUnit5에서는 별도의 의존성을 추가해주어야 한다. junit-jupiter-params 라이브러리에 대한 의존성을 다음과 같이 추가하고 그레이들 동기화를 실행하자.
dependencies {
// JUnit5 테스트 프레임워크
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0")
// Parameterized Test를 위한 라이브러리
testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0")
}
그러면 Parameterized Test를 사용하기 위한 준비가 완료된다.
@ParameterizedTest 사용해 테스트 해보기
앞의 SimpleMultiplier에 대한 테스트를 @ParameterizedTest 를 사용해 변경하면 다음과 같아진다.
class SimpleMultiplierTest {
lateinit var simpleMultiplier: SimpleMultiplier
@BeforeEach
fun setUp() {
simpleMultiplier = SimpleMultiplier()
}
@ParameterizedTest
@ValueSource(
ints = [3, -3, 0]
)
fun `test multiply with inputs`(input: Int) {
// When
val result = simpleMultiplier.multiplyAll(2, input)
// Then
if (input == 0) {
assertEquals(0, result)
} else {
assertEquals(2 * input, result)
}
}
}
@ParameterizedTest는 @ValueSource와 함께 사용되며, @ValueSource에는 다양한 타입에 대한 배열이 들어갈 수 있다. 이렇게 들어간 배열의 각 인자는 각각 테스트 함수의 input 값으로 입력되어 테스트가 실행된다.
따라서 위 테스트를 실행해보면 다음과 같은 결과를 볼 수 있다. 3, -3, 0이 input 값으로 입력 되었을 때 테스트가 모두 통과한 것을 확인할 수 있다.
정리
ParameterizedTest는 다양한 입력값이 들어갈 수 있는 변수에 대한 테스트를 진행할 때 사용할 수 있는 테스트이다. ParameterizedTest를 사용하면, 테스트를 간결하게 만들 수 있다는 장점이 있다. 다만, ParameterizedTest을 남용하면 테스트가 무엇을 뜻하는지 알기 어려워질 수 있으므로, 이런 부분을 잘 고려해서 ParameterizedTest를 사용하도록 하자.