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를 사용하도록 하자.

