Kotest 타임아웃(timeouts)
테스트 시간 초과
Kotest는 두 가지 유형의 테스트 시간 제한을 지원한다. 첫 번째는 테스트의 모든 호출에 대한 전체 시간이다. 이를 타임아웃이라고 한다. 두 번째는 테스트의 개별 실행당이며, 이를 호출 시간 제한이라고 한다.
테스트 시간 제한
테스트 시간 제한을 설정하려면 테스트 구성을 사용하면 된다:
class TimeoutTest : FunSpec({
test("this test will timeout quickly!").config(timeout = 100.milliseconds) {
// test here
}
})
또는 사양 파일의 모든 테스트에 테스트 시간 제한을 적용할 수도 있다:
class TimeoutTest : FunSpec({
timeout = 100.milliseconds
test("this test will timeout quickly!") {
// test here
}
test("so will this one!") {
// test here
}
})
NOTE
테스트에 소요되는 시간에는 중첩된 테스트에 소요되는 실행 시간이 포함되므로 이를 시간 초과에 고려한다.호출 시간 초과
Kotest는 테스트를 여러 번 호출하도록 구성할 수 있다. 예를 들어:
class TimeoutTest : DescribeSpec({
describe("my test context") {
it("run me three times").config(invocations = 3) {
// this test will be invoked three times
}
}
})
그런 다음 invocationTimeout 속성을 사용하여 호출당 타임아웃을 적용할 수 있다.
class TimeoutTest : DescribeSpec({
describe("my test context") {
it("run me three times").config(invocations = 3, invocationTimeout = 60.milliseconds) {
// this test will be invoked three times and each has a timeout of 60 milliseconds
}
}
})
이전 예제에서 각 호출은 60밀리초 이내에 완료되어야 한다. 이를 전체 테스트 시간 초과와 결합할 수 있다:
class TimeoutTest : DescribeSpec({
describe("my test context") {
it("run me three times").config(timeout = 100.milliseconds, invocations = 3, invocationTimeout = 60.milliseconds) {
// this test will be invoked three times
}
}
})
여기서는 세 가지 테스트가 모두 100밀리초 이내에 완료되도록 하되, 특정 호출이 최대 60밀리초까지 연장될 수 있도록 한다.
테스트 타임아웃과 마찬가지로 사양 수준에서 호출 타임아웃을 적용할 수 있다:
class TimeoutTest : FunSpec({
invocationTimeout = 25.milliseconds
test("foo") {
// test here
}
test("bar") {
// test here
}
})
프로젝트 전체 설정
프로젝트 구성을 사용하여 모듈의 모든 테스트에 테스트 및/또는 호출 시간 제한을 적용할 수 있다.
object ProjectConfig : AbstractProjectConfig {
override val timeout = 100.milliseconds
override val invocationTimeout = 33.milliseconds
}
이러한 값은 사양 또는 테스트 수준에서 재정의하지 않는 한 적용된다.
TIP
테스트에 대해 프로젝트 전체 시간 제한을 설정한 다음 사양 또는 테스트별로 재정의할 수 있다.시스템 속성
테스트 시간 제한과 호출 시간 제한은 모두 시스템 속성을 사용하여 설정할 수 있으며, 밀리초 단위로 값을 지정할 수 있다.
kotest.framework.timeout
은 결합된 테스트 시간 제한을 설정한다.kotest.framework.invocation.timeout
은 호출 테스트 시간 제한을 설정한다.
프로젝트 시간 초과
Kotest는 프로젝트 레벨 타임아웃을 지원한다. 이 타임아웃은 모듈의 모든 테스트에 적용되며 모듈의 모든 사양/테스트의 설정/해체 시간을 포함한다.
이를 활성화하려면 ProjectConfig
를 사용하면 된다.
class ProjectConfig : AbstractProjectConfig() {
override val projectTimeout: Duration = 10.minutes
}
위 예제에서는 프로젝트 타임아웃을 10분으로 지정했다. 모든 사양과 테스트는 10분 이내에 완료되어야 하며, 그렇지 않으면 빌드가 실패한다.
테스트 차단
테스트에서 시간 초과를 지정할 때 Kotest는 Kotlin 코루틴 라이브러리가 제공하는 withTimeout 코루틴 함수를 사용한다. 이러한 타임아웃은 본질적으로 협력적이며, 코루틴이 일시 중단, 재개 또는 yield를 호출할 때 타임아웃이 감지된다.
그러나 차단 코드를 실행할 때는 스레드가 차단되므로 협력적 접근 방식이 작동하지 않는다. 이 시나리오에서는 Thread.interrupt 또는 이와 유사한 것을 사용하여 스레드를 중단하는 것으로 되돌려야 한다. 이 중단이 안전하게 작동하려면 전용 스레드에서 테스트를 실행해야 한다.
따라서 특정 테스트가 중단에 안전하게 사용할 수 있는 전용 스레드에서 실행되기를 원한다는 것을 Kotest에 알리는 것은 사용자의 몫이다. 테스트 구성에서 차단 테스트 플래그를 활성화하면 된다.
예를 들어:
class MyBlockingTest : FunSpec() {
init {
test("interrupt me!").config(blockingTest = true, timeout = 10.seconds) {
Thread.sleep(100000000)
}
test("uses suspension").config(timeout = 10.seconds) {
delay(100000000)
}
}
}
위의 예에서 첫 번째 테스트는 스레드 차단 연산을 사용하기 때문에 차단 테스트 플래그가 필요하다. 두 번째 테스트는 일시 중단 가능한 연산을 사용하기 때문에 필요하지 않는다.