코틀린에는 kotest
라는 테스트 프레임워크가 존재합니다. 코틀린을 사용한다면 자바에서 사용하던 assertj
대신 한 번쯤 kotest
를 사용해보는 것도 좋다고 생각합니다.
간단히 java에서 사용하던 방식의 테스트를 작성하고 해당 코드를 kotest
로 변경하는 과정을 소개해보겠습니다.
Quick Start
kotest
는 JUnitPlatform gradle plugin을 사용합니다. 최소 4.6 버전 이상의 Gradle이 필요하기 때문에 버전을 꼭 확인해야 합니다. (최근에는 gradle 7.x 버전이 나오고 있기 때문에 새 프로젝트라면 큰 문제는 없습니다.)
// gradle + groovy
test {
useJUnitPlatform()
}
// dependency
testImplementation 'io.kotest:kotest-runner-junit5:$version'
먼저 위 내용을 build.gradle
에 추가해야 kotest
를 사용하여 테스트를 진행할 수 있습니다.
assertj 전환하기
먼저 간단한 문자열 계산기를 만들고 계산기의 덧셈을 테스트하는 코드를 assertj
로 작성합니다.
@DisplayName("값을 더한다.")
@Test
fun sum() {
val result = StringCalculator.split("1,2,3").sum()
assertThat(result).isEqualTo(6);
}
테스트 코드가 충분히 간결해보이지만, kotest
를 이용하여 조금 더 직관적이고 간결하게 변경할 수 있습니다.
@DisplayName("값을 더한다.")
@Test
fun sum() {
val result = StringCalculator.split("1,2,3").sum()
result shouldBe 6
}
주어진 result
와 결과값 other(6)
이 같다면 테스트는 통과합니다. assertj
를 사용할 때보다 테스트 코드의 작성이 매우 쉬워졌습니다. 또한 kotest-assertions-core
내부의 Matchers 들은 아래와 같은 형태로 사용할 수도 있습니다.
result.shouldBe(6)
이번에는 여러개의 테스트가 하나의 테스트에 존재할 때 kotest
로 전환해보겠습니다.
@DisplayName("숫자를 ,로 구분하면 숫자를 나눈다")
@Test
fun split() {
val stringCalculator = StringCalculator.split("1,2,3")
val numbers = stringCalculator.numbers
assertAll(
{ assertThat(stringCalculator.numbers).hasSize(3) },
{ assertThat(stringCalculator.numbers).contains(1) },
{ assertThat(stringCalculator.numbers).contains(2) },
{ assertThat(stringCalculator.numbers).contains(3) }
)
}
자바 코드와 유사한 형태로 assertAll
내부에 assertThat
여러개가 존재합니다. 이 또한 kotest
의 Soft Assertions
를 통해 해결할 수 있습니다.
@DisplayName("숫자를 ,로 구분하면 숫자를 나눈다")
@Test
fun split() {
val stringCalculator = StringCalculator.split("1,2,3")
val numbers = stringCalculator.numbers
assertSoftly {
numbers shouldHaveSize 3
numbers shouldContain 1
numbers shouldContain 2
numbers shouldContain 3
}
}
내부 assert
내용을 should~
Matcher를 이용해 해결할 수 있습니다. 하지만 더 개선의 여지가 있습니다.
@DisplayName("숫자를 ,로 구분하면 숫자를 나눈다")
@Test
fun split() {
val stringCalculator = StringCalculator.split("1,2,3")
val numbers = stringCalculator.numbers
assertSoftly(numbers) {
shouldHaveSize(3)
shouldContain(1)
shouldContain(2)
shouldContain(3)
}
}
Soft Assertions
가 이뤄질 내부에서 사용할 인스턴스를 람다를 통해 마음껏 사용할 수 있습니다. 람다를 명시적으로 사용하고 싶다면 it
키워드를 사용하면 됩니다.
assertSoftly(numbers) {
it[0] shouldBe 1
it[1] shouldBe 2
it[2] shouldBe 3
}
이번에는 번호를 랜덤으로 발생시키고 해당 번호가 0 ~ 9 사이인지 테스트하는 메서드를 작성해보겠습니다.
@DisplayName("generate 시 입력한 파라미터 범위 내의 숫자를 발생한다.")
@Test
fun generateInRange() {
val randoms = Randoms(3)
val moveFactors = randoms.generate()
assertAll(
{ assertThat(moveFactors[0]).isLessThan(10).isGreaterThanOrEqualTo(0) },
{ assertThat(moveFactors[1]).isLessThan(10).isGreaterThanOrEqualTo(0) },
{ assertThat(moveFactors[2]).isLessThan(10).isGreaterThanOrEqualTo(0) }
)
}
요소 하나하나가 0보다 크거나 같고, 10보다 작은지 확인하고 있습니다. 이 코드 또한 아래와 같이 개선할 수 있습니다.
@DisplayName("generate 시 입력한 파라미터 범위 내의 숫자를 발생한다.")
@Test
fun generateInRange() {
val randoms = Randoms(3)
val moveFactors = randoms.generate()
moveFactors.forAll {
it.shouldBeBetween(0, 9)
}
}
kotest
의 Inspector
를 사용하여 collection
의 내부 요소를 직접 테스트할 수 있습니다.
kotest를 보면 여러 다양한 테스트 방법이 존재합니다. kotlin
에 관심이 있다면 한 번쯤 어떤 기술이 있는지 관심 가져볼만 하고, kotlin
을 공부하고 있다면 꼭 살펴보고 직접 사용해보는 것도 좋을 것 같습니다!