You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cucumber-JVM是否支持通过步骤名称调用步骤实现软执行?

问题

之前在Stack Overflow上了解到,cuke4duke可以通过继承Steps类在步骤定义中调用其他步骤,示例代码如下:

// 在Java中调用步骤定义内的步骤,需继承cuke4duke.Steps
import cuke4duke.StepMother;
import cuke4duke.Steps;
import cuke4duke.annotation.I18n.EN.When;

public class CallingSteps extends Steps {
    public CallingSteps(StepMother stepMother) {
        super(stepMother);
    }

    @When("^I call another step$")
    public void iCallAnotherStep() {
        Given("it is magic"); // 调用其他地方定义的步骤
    }
}

但cuke4duke已经废弃12年,Cucumber-JVM是它的继任者,想请教:Cucumber-JVM是否支持类似通过步骤名称在步骤定义中调用其他步骤的功能?

另外希望实现一个通用的Kotlin方法,传入步骤名称就能调用对应步骤,在try-catch块中执行并记录异常,让这个步骤成为不会导致场景失败的「软执行」版本,而且新增步骤时不需要更新这个方法,预期代码示例如下:

@When("soft call the step {string}")
fun softCall(stepToCall: String) {
    runCatching {
        Given(stepToCall) // 调用其他地方定义的步骤
    }.onFailure { 
        // 记录异常
    }
}
回答

Cucumber-JVM确实支持在步骤定义中调用其他步骤,但和cuke4duke的实现方式不同,不需要继承特定类,可通过Cucumber提供的API动态查找并执行步骤。

通用软调用步骤的Kotlin实现方案

要实现你想要的「软执行」逻辑,无需为新增步骤修改方法,可以借助Cucumber的StepDefinitionRegistry和StepExpressionFactory来动态匹配并调用步骤,代码如下:

import io.cucumber.java.en.When
import io.cucumber.core.api.Scenario
import io.cucumber.core.stepexpression.StepExpressionFactory
import io.cucumber.core.registry.StepDefinitionRegistry
import java.util.Locale
import javax.inject.Inject

class SoftStepCaller {

    @Inject
    private lateinit var stepDefinitionRegistry: StepDefinitionRegistry

    @Inject
    private lateinit var locale: Locale

    @When("soft call the step {string}")
    fun softCall(stepToCall: String, scenario: Scenario) {
        runCatching {
            // 根据步骤文本创建表达式,用于匹配已定义的步骤
            val stepExpression = StepExpressionFactory(locale).createExpression(stepToCall)
            // 查找匹配的步骤定义
            val match = stepDefinitionRegistry.lookupStepDefinition(stepExpression)
                ?: throw IllegalArgumentException("找不到匹配的步骤:$stepToCall")
            
            // 执行找到的步骤
            match.execute(scenario)
        }.onFailure { exception ->
            // 记录异常,可写入场景报告或日志
            scenario.write("软执行步骤失败:${exception.message}")
            scenario.embed(exception.stackTraceToString().toByteArray(), "text/plain")
        }
    }
}

关键说明

  • 动态匹配步骤:通过StepDefinitionRegistry和StepExpressionFactory,能根据传入的步骤文本自动匹配已注册的步骤,新增步骤时无需修改该方法。
  • 软执行逻辑:用runCatching捕获所有异常,执行失败仅记录信息,不会中断整个场景。
  • 依赖注入:Cucumber-JVM会自动注入StepDefinitionRegistry和Locale,无需手动初始化,确保能获取所有已定义的步骤。

注意事项

  • 传入的步骤文本需要和原步骤定义的表达式完全匹配,包括参数内容。比如原步骤是Given "I have {int} apples",传入的文本需是"I have 5 apples"这类完整格式。
  • 若步骤包含参数,要确保传入文本的参数格式正确,否则会匹配失败或执行出错。

内容的提问来源于stack exchange,提问作者Bar_g5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:07:49