【问题标题】:Cucumber pass whole example to a stepCucumber 将整个示例传递给一个步骤
【发布时间】:2021-02-17 14:39:04
【问题描述】:

我想将整个示例作为 Map 对象传递给某个测试步骤。如何实现?

假设我有场景

Scenario Outline: some description text
When user do something
Then the user should see something
Examples: set 1
  | Param Title |
  | value 1     |
Examples: set 2
  | Param Title | Param Title 2 |
  | value 2     | value 3       |

When user do something 的步骤定义中,我想要一个映射,第一个示例包含映射{"Param Title":"value 1"},第二个示例包含{"Param Title":"value 2","Param Title 2":"value 3"}。有没有办法在黄瓜中做到这一点,或者我唯一的选择是为每个示例多次编写相同的场景?

【问题讨论】:

    标签: java cucumber scenarios


    【解决方案1】:

    与尝试将地图传递到通用步骤定义中所增加的复杂性相比,编写步骤定义的成本微不足道。

    如果您将所有步骤定义实现为对辅助方法的单个调用,那么您是否有很多执行相同操作的步骤定义并不重要。当您遵循此模式时,您的步骤定义执行一个功能,它们将字符串短语转换为方法调用。

    让我举几个例子

    Given I am logged in
    Given I am logged in as an admin
    Given Fred is logged in
    Given Bill is logged in
    Given Sam is logged in as an admin
    

    现在您可能只想为所有这些编写一个步骤定义,但这实际上是一个错误和错误的优化。执行以下操作要简单得多(所有示例都在 ruby​​ 中)

    Given 'I am logged in' do
      @i ||= create_user
      login as: @i
    end
    
    Given 'I am logged in as an admin' do
      @i ||= create_admin
      admin_login as: @i
    end
    
    Given 'Fred is logged in' do
      @fred ||= create_user(first_name: 'Fred')
      login as: @fred
    end
    
    Given 'Bill is logged in' do
      @bill ||= create_user(first_name: 'Bill')
      login as: @fred
    end
      
    Given 'Sam is logged in as an admin' do
      @sam ||= create_admin(first_name: 'Sam')
      login as: @sam
    end
    

    这里的所有工作都是由辅助方法(create_user、create_admin、login、admin_login)完成的,所以如果你有 20 步定义来登录并不重要,只要它们都使用辅助方法来完成您的工作没有真正的代码重复,并且您具有简单性和一致性。

    这与您当前采用的方法完全不同。但是,对于任何涉及使用步骤和步骤定义做复杂事情的问题,一个有效的答案是停止尝试做复杂的事情,而是做更简单的事情。

    【讨论】:

    • 这实际上是一个非常好的主意。我从来没有想过这种方式。但在我的情况下实施它会复杂得多。原因是: 1. 我正在尝试填写动态表格。 2. 所有这些表格包含最少 10 个参数 3. 一些参数是可选的 4. 在某些测试中,它们在其他测试中不使用 5. 许多表格选择为每种类型附加不同的表格 6. 同样对于相同的表格,它们是不同的变体
    • 所以你可以想象在我的例子中这样做意味着如何实现不同变体的步骤、类和方法的爆炸式增长。所以我想出了一个想法,编写一个简单的类来检查任务名称并将其与 Map 的键进行比较以查看它是否存在。如果是,则执行它(例如选择,输入单击等),否则请忽略它。使用它,我正在填写相同的表单,成本要低得多,并且可重用性高。
    • 因此您需要找出为什么某些字段在某些测试中填写而其他字段未填写。然后为参数集命名。诸如good_data,bad_data,options_supplied等之类的东西。然后制作处理参数集的方法,例如fill_in_good_data 等。这样做会得到一个小的填充方法层次结构,您可以使用这些方法通过单个简单的步骤定义填充表单,并且您填写的字段的详细信息都不需要出现在场景中.
    • 不,我认为从文件加载不是一个好主意,因为控制从源(可见)移到文件(不那么可见)中。大多数情况下,您可以通过创建假数据或使用常量从代码中加载数据,数据实际上并没有那么相关,重要的是数据的意图,即您在使用时尝试做什么一组特定的数据。
    • 酷,如果你觉得有用,请考虑接受这个答案
    【解决方案2】:

    你可以在特征文件中写如下,其中参数标题被定义为列

    When user do something <Param Title>
    
    

    在步骤定义中,您可以编写。这样一来,您就不必一次又一次地编写场景,您可以将多个示例编写为一个示例集中的多行

    @When("user do something ([^\"]*)")
    public void useractivity(String Title){
    
    }
    

    【讨论】:

    • 我的问题是如何将整个示例发送到步骤。就像某些步骤接受可变数量的参数一样。但是由于场景的编写方式,必须定义步骤应该使用的参数
    • 当用户做某事时你可以写成如下|参数标题|| |参数标题2|
    • 再次,我需要传递可变数量的参数。举一个例子,它们是 2。对于下一个例子,它们可能是 1 或 7 或 3。按照您的建议进行操作需要在 step 下列出参数。一旦列出,它只会传递那些除非我创建新场景来列出不同的参数。
    • 因为有很多参数,所以步骤下的数据表中会有很多行。在 Stepdefinition 中,它将作为一个 List 并具有尽可能多的行,将添加许多键和值
    • 举个你的例子。在表中,您传递了我之前评论中提到的 2 个参数。在示例 1 中,您将一个空白值传递给 Param Title 2,而在示例集 2 中,您为两个示例 Param Title 传递了一个值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多