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

如何组织Behat的Features目录与Context类以复用相同步骤?

Behat 通用步骤重复定义问题解决

我有2个Feature,每个Feature对应一个Context类(RegisterVehcileContext和ParkVehicleContext)。这两个Feature存在通用步骤,因此我创建了Trait来存放这些步骤,但Behat提示「步骤已定义」的错误。我可以在各Context中重复编写通用步骤并改用不同名称,但不愿重复代码。

(错误提示截图:显示Behat报错步骤已被多个上下文重复定义)

我的behat.yml配置如下:

default:
  suites:
    web:
      contexts:
        - RegisterVehcileContext
        - ParkVehicleContext

解决方案

方案1:抽离通用步骤为独立Context

Behat允许在Suite中加载多个Context,你可以把通用步骤放到独立的CommonContext类中,直接在配置里引入这个Context,无需用Trait混入业务Context:

修改behat.yml:

default:
  suites:
    web:
      contexts:
        - CommonContext
        - RegisterVehcileContext
        - ParkVehicleContext

CommonContext示例代码:

use Behat\Behat\Context\Context;

class CommonContext implements Context
{
    /**
     * @Given 我已登录系统
     */
    public function iAmLoggedIn()
    {
        // 通用步骤逻辑实现
    }
}

这种方式下,Behat会自动识别所有Context中的步骤,不会出现重复定义问题,同时完全避免代码重复。

方案2:Trait复用时避免重复加载

如果坚持使用Trait,需要确保同一个Trait不会被多个Context同时加载到同一个Suite中:

  • 仅将Trait混入到一个业务Context,其他Context通过依赖注入调用该Context的通用方法
  • 拆分Suite,让每个Suite中只有一个Context使用该Trait

方案3:通过方法调用复用逻辑(不推荐)

在业务Context中调用通用步骤的逻辑,而非直接复用注解:
比如在ParkVehicleContext中:

use Behat\Behat\Context\Context;
use RegisterVehcileContext;

class ParkVehicleContext implements Context
{
    private $registerContext;

    public function __construct(RegisterVehcileContext $registerContext)
    {
        $this->registerContext = $registerContext;
    }

    /**
     * @Given 我已登录系统
     */
    public function iAmLoggedIn()
    {
        $this->registerContext->iAmLoggedIn();
    }
}

这种方式仍可能触发步骤重复定义提示,仅作为临时替代方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:07:19