Kotest

dependencies {
    testImplementation("dev.tracera:tracera-kotest:<version>")
}

Requires JDK ≥ 17 and Kotest ≥ 6 (see Autotest adapters). tracera-kotest on Maven Central.

Environment variables, run mode, and retries: Autotest adapters.

Retry Env key: KOTEST_RETRY.

Register the extension in project config:

import dev.tracera.TraceraKotestExtension
import io.kotest.core.config.AbstractProjectConfig

class ProjectConfig : AbstractProjectConfig() {
    override fun extensions() = listOf(TraceraKotestExtension())
}

Bind testCaseId and autotestName

Import stock Kotest Spec APIs, and Tracera from dev.tracera.

At declaration (preferred — Spec-level for FunSpec; method-level on AnnotationSpec @Test):

import dev.tracera.Tracera
import io.kotest.core.spec.style.FunSpec

@Tracera.Id(42, name = "e2e/login")
class LoginSpec : FunSpec({
    test("login") {
        // …
    }
})

Inside the test:

import dev.tracera.Tracera
import io.kotest.core.spec.style.FunSpec

class LoginSpec : FunSpec({
    test("login") {
        Tracera.testCase(42, "e2e/login")
    }
})

Skip

Use stock Kotest skip (enabled = { … }, Assume.that, …). The skip reason is added to the result as comment.

Steps

Use Tracera.step("…") { … }, Tracera.suspendStep("…") { … } for coroutines, or put @Tracera.Step("…") on a method (sync and suspend). With @Tracera.Step, if the title is empty or omitted, the step title becomes the method name; {0} / {name} in the title are filled from the method arguments. Per-test hooks map to Setup / Teardown; Spec-level suite hooks are not reported.

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") { }
    }
}

Comments, errors, and attachments

Comments, errors, and attachments: Autotest adapters.

Tracera.comment("result-level note")
Tracera.error("result-level error text")
Tracera.step("open login") {
    Tracera.comment("landed on login")
}

Parameterized tests

In FunSpec, make a separate test per data row: test("ok") { … }, test("sso") { … }. Put @Tracera.Id on the Spec class; optional name may use {param_id}, which becomes that test’s name ("ok", "sso"). In AnnotationSpec, @Test methods take no arguments, so placeholders like {login} from parameters are not available — {param_id} is the Kotlin method name; to include row fields in the name, call Tracera.testCase inside the test. If name is omitted, autotestName takes the value of the Kotest test name.

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())
        }
    }
})