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

Cucumber Ruby中能否为Given/Then步骤定义添加命名空间?

Cucumber Ruby 步骤定义同名问题解决方法

首先明确:你之前用Scenario()包裹步骤定义的写法是错误的——Scenario是Feature文件中的Gherkin关键字,不能在Ruby步骤定义文件中作为方法调用,因此会提示Scenario不是有效方法。

Cucumber Ruby本身不支持直接给步骤定义添加命名空间,但可以通过以下几种方式实现不同场景绑定独立的同名步骤逻辑:


方案1:标签+钩子+实例变量区分场景

给每个场景添加专属标签,通过Before钩子根据标签设置上下文变量,在同名步骤中根据变量执行不同逻辑。

修改后的Feature文件

@jobdataAPI
Feature: Submitting a toolbox talk request

  @first-aid-no
  Scenario: When submitting with first aid kit with NO selected, open an HR ticket
    Given first aid kit NO
    Then open an HR ticket

  @first-aid-stocked-no
  Scenario: When submitting with first aid kit fully stocked NO, open an HR ticket
    Given first aid kit fully stocked NO
    Then open an HR ticket

  @fire-extinguisher-no
  Scenario: When submitting fire extinguisher NO, open an HR ticket
    Given fire extinguisher NO
    Then open an HR ticket

对应的步骤定义

# frozen_string_literal: true

World JOBDATA

# 为每个标签设置上下文变量
Before('@first-aid-no') do
  @ticket_context = :first_aid_no
end

Before('@first-aid-stocked-no') do
  @ticket_context = :first_aid_stocked_no
end

Before('@fire-extinguisher-no') do
  @ticket_context = :fire_extinguisher_no
end

# 各场景独立的Given步骤
Given('first aid kit NO') do
  # 第一个场景的前置逻辑
end

Given('first aid kit fully stocked NO') do
  # 第二个场景的前置逻辑
end

Given('fire extinguisher NO') do
  # 第三个场景的前置逻辑
end

# 同名Then步骤根据上下文执行不同逻辑
Then('open an HR ticket') do
  case @ticket_context
  when :first_aid_no
    # 第一个场景的HR工单逻辑
  when :first_aid_stocked_no
    # 第二个场景的HR工单逻辑
  when :fire_extinguisher_no
    # 第三个场景的HR工单逻辑
  end
end

方案2:通过Given步骤记录状态

在每个Given步骤中记录当前设备的状态信息,Then步骤根据该状态执行对应逻辑。

步骤定义示例

# frozen_string_literal: true

World JOBDATA

Given('first aid kit NO') do
  @equipment = { type: :basic_first_aid, status: :not_selected }
end

Given('first aid kit fully stocked NO') do
  @equipment = { type: :stocked_first_aid, status: :not_available }
end

Given('fire extinguisher NO') do
  @equipment = { type: :fire_extinguisher, status: :not_available }
end

Then('open an HR ticket') do
  case @equipment[:type]
  when :basic_first_aid
    # 对应第一个场景的工单逻辑
  when :stocked_first_aid
    # 对应第二个场景的工单逻辑
  when :fire_extinguisher
    # 对应第三个场景的工单逻辑
  end
end

方案3:模块化封装+标签加载

将不同场景的步骤逻辑封装到独立模块中,通过Before钩子根据标签动态加载对应模块,实现步骤定义的隔离。

步骤定义示例

# frozen_string_literal: true

World JOBDATA

# 封装第一个场景的步骤逻辑
module FirstAidNoSteps
  def self.included(base)
    base.class_eval do
      Given('first aid kit NO') do
        # 第一个场景的前置逻辑
      end

      Then('open an HR ticket') do
        # 第一个场景的工单逻辑
      end
    end
  end
end

# 封装第二个场景的步骤逻辑
module FirstAidStockedNoSteps
  def self.included(base)
    base.class_eval do
      Given('first aid kit fully stocked NO') do
        # 第二个场景的前置逻辑
      end

      Then('open an HR ticket') do
        # 第二个场景的工单逻辑
      end
    end
  end
end

# 封装第三个场景的步骤逻辑
module FireExtinguisherNoSteps
  def self.included(base)
    base.class_eval do
      Given('fire extinguisher NO') do
        # 第三个场景的前置逻辑
      end

      Then('open an HR ticket') do
        # 第三个场景的工单逻辑
      end
    end
  end
end

# 根据标签加载对应模块
Before('@first-aid-no') do
  self.class.send(:include, FirstAidNoSteps)
end

Before('@first-aid-stocked-no') do
  self.class.send(:include, FirstAidStockedNoSteps)
end

Before('@fire-extinguisher-no') do
  self.class.send(:include, FireExtinguisherNoSteps)
end

以上三种方案中,方案1和方案2属于轻量实现,适合大多数场景;方案3适合逻辑复杂、需要完全隔离步骤的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:40:36