Kotest
dependencies {
testImplementation("dev.tracera:tracera-kotest:<version>")
}
需要 JDK ≥ 17 和 Kotest ≥ 6(见 自动化测试适配器)。tracera-kotest on Maven Central。
环境变量、运行模式与重试:自动化测试适配器。
重试 Env 键:KOTEST_RETRY。
在项目配置中注册扩展:
import dev.tracera.TraceraKotestExtension
import io.kotest.core.config.AbstractProjectConfig
class ProjectConfig : AbstractProjectConfig() {
override fun extensions() = listOf(TraceraKotestExtension())
}
绑定 testCaseId 与 autotestName
照常使用 Kotest Spec 标准 API,并从 dev.tracera 导入 Tracera。
在声明时(推荐 — FunSpec 用 Spec 级;AnnotationSpec 的 @Test 用方法级):
import dev.tracera.Tracera
import io.kotest.core.spec.style.FunSpec
@Tracera.Id(42, name = "e2e/login")
class LoginSpec : FunSpec({
test("login") {
// …
}
})
在测试内:
import dev.tracera.Tracera
import io.kotest.core.spec.style.FunSpec
class LoginSpec : FunSpec({
test("login") {
Tracera.testCase(42, "e2e/login")
}
})
Skip
使用 Kotest 标准 skip(enabled = { … }、Assume.that 等)。Skip 原因会作为 comment 写入结果。
步骤
使用 Tracera.step("…") { … }、Tracera.suspendStep("…") { … }(协程),或在方法上使用 @Tracera.Step("…")(sync 与 suspend)。@Tracera.Step 标题为空或未写时,步骤标题使用方法名;标题中的 {0} / {name} 从方法参数填入。每个测试的钩子映射到 准备 / 清理;Spec 级套件钩子不上报。
import dev.tracera.Tracera
import io.kotest.core.spec.style.AnnotationSpec
class CheckoutSpec : AnnotationSpec() {
@Tracera.Step("add {sku}")
fun addSku(sku: String) {
}
@Tracera.Id(10, name = "e2e/checkout")
@Test
fun checkout() {
addSku("SKU-1")
Tracera.step("pay") { }
}
}
注释、错误与附件
注释、错误与附件:自动化测试适配器。
Tracera.comment("result-level note")
Tracera.error("result-level error text")
Tracera.step("open login") {
Tracera.comment("landed on login")
}
参数化测试
在 FunSpec 中为每一行数据写一个独立测试:test("ok") { … }、test("sso") { … }。把 @Tracera.Id 放在 Spec 类上;可选 name 可用 {param_id},会替换为该测试名("ok"、"sso")。AnnotationSpec 的 @Test 方法没有参数,因此无法用 {login} 这类来自参数的占位符——{param_id} 是 Kotlin 方法名;若名称要包含行字段,在测试内调用 Tracera.testCase。若未指定 name,则 autotestName 取 Kotest 测试名。
import dev.tracera.Tracera
import io.kotest.core.spec.style.FunSpec
@Tracera.Id(42, name = "login as {param_id}")
class LoginSpec : FunSpec({
for (login in listOf("ok", "sso")) {
test(login) {
assert(login.isNotEmpty())
}
}
})