Kotest 소프트 단어문(Soft Assertions)
Soft Assertions
일반적으로 shouldBe
와 같은 단언문은 실패하면 바로 예외를 던진다. 그렇게 되면, 나중에 위치한 단언문은 결과를 볼 수 없게 된다. 그러나 때로는 테스트에서 여러 단언문을 수행하고 실패한 모든 단언문을 보고 싶을 때가 있다. Kotest는 이를 위해 assertSoftly
함수를 제공한다.
assertSoftly {
foo shouldBe bar
foo should contain(baz)
}
단순히 shouldBe
와 같은 Matcher를 여러번 수행함으로써 다수의 단언을 수행할 수 있지만 이런 경우 앞선 단언이 실패하는 경우 후속 단언을 수행하지 않고 테스트가 멈추기 때문에 후속 단언의 성공여부를 앞선 단언이 성공하기 전까지 판단하기 어렵다.
assertSoftly
를 사용하면, 하나의 Assertion이 실패하더라도 그룹 내의 나머지 Assertion이 실행되며 테스트가 계속 진행된다. 즉, assertSoftly
는 모든 Assertion을 실행하고 결과를 모으는 방식으로 동작한다. 참고로, JUnit의 assertAll
과 동일하게 동작한다.
assertSoftly
는 주로 여러 부분의 동작을 동시에 테스트하거나, 특정 상태를 검증할 때 유용한다. 실패한 Assertion의 위치를 정확히 파악하고자 할 때도 유용하게 사용될 수 있다.
예를 들면, 데이터 검증시에 equals
로 객체의 프로퍼티들을 검증할 때 주로 사용하면 유용하다.
assertSoftly
를 사용하게 되면 블록 내부의 단언문이 실패하도 테스트는 계속 실행된다. 모든 실패는 블록이 끝나고 나서 단일 예외로 보고된다.
또 다른 버전의 assertSoftly
는 테스트 대상과 테스트 대상을 수신자로 하는 람다를 사용한다.
assertSoftly(foo) {
shouldNotEndWith("b")
length shouldBe 3
}
다음은 assertSoftly
의 간단한 사용 예제이다:
package com.devkuma.kotest.tutorial.assertions
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import io.kotest.assertions.assertSoftly
class SoftAssertionTest : StringSpec({
"assertSoftly를 사용한 테스트" {
val person = Person(
"devkuma",
30
)
assertSoftly {
person.name shouldBe "devkuma"
person.age shouldBe 30
}
}
})
data class Person(
val name: String,
val age: Int
)
위의 코드에서는 assertSoftly
블록 내에서 여러 Assertion을 그룹화하여 실행하고 있다. 만약 하나의 Assertion이 실패하더라도, 나머지 Assertion은 여전히 실행되며 테스트가 중단되지 않는다. 이렇게 함으로써 한 번에 여러 가지 조건을 동시에 테스트할 수 있다.
프로젝트 구성을 통해 모든 테스트에 암묵적으로 단언문이 추가되도록 소프트하게 구성할 수 있다.