JUnit 5

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

需要 JDK ≥ 17 和 JUnit ≥ 5.8(见 自动化测试适配器)。tracera-junit5 on Maven Central。

环境变量、运行模式与重试:自动化测试适配器。

重试 Env 键:JUNIT_RETRY。

在项目中启用扩展自动注册(每个项目一次):

# src/test/resources/junit-platform.properties
junit.jupiter.extensions.autodetection.enabled=true

或显式注册:@ExtendWith(TraceraExtension::class)。

绑定 testCaseId 与 autotestName

照常使用 JUnit Jupiter 标准 API,并从 dev.tracera 导入 Tracera。

在声明时(推荐 — 即使测试体提前跳过也会绑定):

import dev.tracera.Tracera
import org.junit.jupiter.api.Test

class LoginTest {
    @Tracera.Id(42, name = "e2e/login")
    @Test
    fun login() {
        assert(true)
    }
}

在测试内:

import dev.tracera.Tracera
import org.junit.jupiter.api.Test

class LoginTest {
    @Test
    fun login() {
        Tracera.testCase(42, "e2e/login")
        assert(true)
    }
}

Skip

使用 JUnit 标准 skip(Assumptions.abort、@Disabled 等)。Skip 原因会作为 comment 写入结果。

步骤

使用 Tracera.step("…") { … }、Tracera.suspendStep("…") { … }(协程),或在方法上使用 @Tracera.Step("…")(sync 与 suspend)。@Tracera.Step 标题为空或未写时,步骤标题使用方法名;标题中的 {0} / {name} 从方法参数填入。@BeforeEach / @AfterEach 内的步骤进入结果的 准备 / 清理;测试内的步骤进入 测试。@BeforeAll / @AfterAll 不上报。

import dev.tracera.Tracera
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class CheckoutTest {
    @BeforeEach
    fun openShop() {
        Tracera.step("open shop") { }
    }

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

参数化测试

在每个 @ParameterizedTest 方法上放 @Tracera.Id(各行共用同一 id,或在方法内调用 Tracera.testCase 按行变化)。可选 name 可含占位符:{login} 等来自方法参数名,或 {param_id}(JUnit 测试名)。若未指定 name,则 autotestName 取 JUnit 测试名。

@Tracera.Id(42, name = "login as {login}")
@ParameterizedTest
@ValueSource(strings = ["ok", "sso"])
fun login(login: String) {
    assert(login.isNotEmpty())
}