
안녕하세요.
Parameterized Test에 대해서 알아보겠습니다.
Parameterized Test
Parameterized Test란 여러 세트의 데이터를 사용하여 동일한 테스트 메서드를 여러 번 실행할 수 있게 하는 기능입니다.
- 반복적인 테스트 코드를 줄일 수 있는 장점이 있습니다.
- 다양한 입력에 대해 테스트를 쉽게 수행할 수 있는 장점이 있습니다.
Annotation
Parameterized Test를 사용하는 주요 어노테이션으로는 아래와 같습니다.
- @ParameterizedTest : 파라미터 테스트 메서드를 나타냄
- @ValueSource : 단일 값 배열을 제공함
- @CsvSource : 여러 Csv 값을 제공함
- @MethodSource : 메서드를 통해 테스트 데이터를 제공함
- @ArgumentsSource : 클래스를 통해 테스트 데이터를 제공함
Use in Android Studio
지난 포스팅에서 설정한 build.gradle (app) 에서 아래 부분을 추가해줍니다.
dependencies {
...
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
}
https://kdr06006.tistory.com/50
[Unit Test] JUnit5 (1) - Use in Android Studio
안녕하세요.Unit Test 프레임워크 중 하나인 JUnit5에 대해 알아보겠습니다.JUnit5JVM 기반 언어에서 단위 테스트를 작성하고 실행하는데 사용되는 프레임워크입니다.그래서 Java, Kotlin 언어로 개발할
kdr06006.tistory.com
@ValueSource
단일 값 배열을 테스트 메서드에 제공할 때 사용합ㄴ디ㅏ.
아래와 같이 MathUtils.kt를 만들어주고 이 클래스를 테스트해 보겠습니다.
package com.example.kotlinpractice.junit
class MathUtils {
fun isEven(number: Int): Boolean {
return number % 2 == 0
}
}
@ValueSource() 인자로 int 배열을 선언해 테스트 메서드에 제공합니다.
여러 input들을 하나의 메서드로 테스트할 수 있는걸 볼 수 있습니다.
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
class MathUtilsTest {
private val mathUtils = MathUtils()
@ParameterizedTest
@ValueSource(ints = [2, 4, 6, 8, 10])
@DisplayName("test isEven when number is even")
fun `test - isEven() is true`(number: Int) {
assertTrue(mathUtils.isEven(number))
}
@ParameterizedTest
@ValueSource(ints = [1, 3, 5, 7, 9])
@DisplayName("test isEven when number is odd")
fun `test - isEven() is false`(number: Int) {
assertFalse(mathUtils.isEven(number))
}
}
테스트가 잘 된 것을 볼 수 있습니다.

만약에 실패하면 이렇게 뜹니다.

+) 가능한 타입
@ValueSource() 안에 인자로 들어갈 타입의 유형으로는 아래와 같습니다.
- short, byte, int, long, float, double, char, boolean,
- java.lang.String, java.lang.Class
@CsvSource
Csv 형식으로 여러 인자를 테스트 메서드에 제공할 수 있습니다.
아래와 같이 Calculator.kt를 만들고 테스트를 진행해 보겠습니다.
package com.example.kotlinpractice.junit
class Calculator {
fun add(a: Int, b: Int): Int {
return a + b
}
fun subtract(a: Int, b: Int): Int {
return a - b
}
}
여러 input을 넣어서 테스트를 한 번에 진행하는 모습입니다.
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
class CalculatorTest {
private val calculator = Calculator()
@ParameterizedTest
@CsvSource(
"1, 1, 2",
"2, 3, 5",
"5, 8, 13",
"10, 10, 20"
)
fun testAdd(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.add(a, b))
}
@ParameterizedTest
@CsvSource(
"5, 3, 2",
"10, 5, 5",
"20, 4, 16",
"15, 10, 5"
)
fun testSubtract(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.subtract(a, b))
}
}
@MethodSource
테스트 데이터를 메서드에서 제공받아 사용합니다.
복잡한 테스트 데이터나, 여러 테스트 함수에 파라미터로 사용될 때 사용합니다.
데이터 제공 메서드는 아래 조건을 만족해야 합니다.
- 특정 Collection이나 Stream을 반환해야 함
- static function 이어야 함
테스트 제공 메서드로 static function을 만듭니다.
그리고 @MethodSource() 인자로 해당 함수를 주면 됩니다.
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream
class CalculatorTest {
private val calculator = Calculator()
companion object {
@JvmStatic
fun provideAddData(): Stream<Arguments> {
return Stream.of(
Arguments.of(1, 1, 2),
Arguments.of(2, 3, 5),
Arguments.of(5, 8, 13),
Arguments.of(10, 10, 20)
)
}
@JvmStatic
fun provideSubtractData(): List<Arguments> {
return listOf(
Arguments.of(5, 3, 2),
Arguments.of(10, 5, 5),
Arguments.of(20, 4, 16),
Arguments.of(15, 10, 5)
)
}
}
@ParameterizedTest
@MethodSource("provideAddData")
fun testAdd(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.add(a, b))
}
@ParameterizedTest
@MethodSource("provideSubtractData")
fun testSubtract(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.subtract(a, b))
}
}
데이터 제공 부분과 실제 테스트 부분을 분리할 수 있어 좋습니다.
@ArgumentsSource
테스트 데이터를 외부 클래스에서 제공받아 사용합니다.
데이터를 제공할 외부 클래스는 ArgumentsProvider 인터페이스를 구현해 사용하면 됩니다.
테스트 데이터를 제공하는 Custom ArgumentsProvider 클래스 입니다.
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
import java.util.stream.Stream
class AddArgumentsProvider : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext): Stream<out Arguments> {
return Stream.of(
Arguments.of(1, 1, 2),
Arguments.of(2, 3, 5),
Arguments.of(5, 8, 13),
Arguments.of(10, 10, 20)
)
}
}
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
import java.util.stream.Stream
class SubtractArgumentsProvider : ArgumentsProvider {
override fun provideArguments(context: ExtensionContext): Stream<out Arguments> {
return Stream.of(
Arguments.of(5, 3, 2),
Arguments.of(10, 5, 5),
Arguments.of(20, 4, 16),
Arguments.of(15, 10, 5)
)
}
}
테스트 클래스에서 위에서 만든 클래스를 @ArgumentsSource() 인자로 주면 됩니다.
package com.example.kotlinpractice.junit
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ArgumentsSource
class CalculatorTest {
private val calculator = Calculator()
@ParameterizedTest
@ArgumentsSource(AddArgumentsProvider::class)
fun testAdd(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.add(a, b))
}
@ParameterizedTest
@ArgumentsSource(SubtractArgumentsProvider::class)
fun testSubtract(a: Int, b: Int, expected: Int) {
assertEquals(expected, calculator.subtract(a, b))
}
}
참고 자료
[JUnit] @ParameterizedTest - @MethodSource 사용하기
들어가며 이전에 'Parameterized Test - 테스트를 효율적으로'라는 글을 올렸었는데 전부 학습한 내용이 아니라서 이번에 사용한 기능을 추가로 포스팅하려고 합니다. 이전에 다뤘던 테스트는 클래스
ebabby.tistory.com
'Unit Test' 카테고리의 다른 글
[Unit Test] MockK (2) - mockkObject, mockkStatic, mockkConstructor (0) | 2024.09.30 |
---|---|
[Unit Test] MockK (1) - Mock, Spy (0) | 2024.08.11 |
[Unit Test] JUnit5 (1) - Use in Android Studio (1) | 2024.06.29 |