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
相关产品推荐
相关产品推荐

