Testing Codes/JUnit5

[JUnit5] @ParameterizedTest 사용해 서로 다른 변수를 사용해 테스트 실행하기

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 값으로 입력되어 테스트가 실행된다.

그림1. ValueSource

따라서 위 테스트를 실행해보면 다음과 같은 결과를 볼 수 있다. 3, -3, 0이 input 값으로 입력 되었을 때 테스트가 모두 통과한 것을 확인할 수 있다.

그림2. ParameterizedTest 실행 결과

 

정리

ParameterizedTest는 다양한 입력값이 들어갈 수 있는 변수에 대한 테스트를 진행할 때 사용할 수 있는 테스트이다. ParameterizedTest를 사용하면, 테스트를 간결하게 만들 수 있다는 장점이 있다. 다만, ParameterizedTest을 남용하면 테스트가 무엇을 뜻하는지 알기 어려워질 수 있으므로, 이런 부분을 잘 고려해서 ParameterizedTest를 사용하도록 하자.

반응형

 

이 글의 저작권은 Dev World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com