在Cucumber的Examples中传递带hash的Array

Array中带有 Hash。

问题描述

在Cucumber中,当你需要在Examples中传递Array的时候,只需要用逗号分隔即可,比如下面这种:

Scenario Outline: check cart
    When I am "<username>", I check my cart
    Then I will see the product lists is "<products>"
    Examples:
    | username | products |
    |  Tom | Apple, Banana, Blackberry, Orange |
    |  Lucy | Apple, Blackberry, Orange, Lemon |
    |  Jim | Blueberry, Orange, Lemon |

然后在对应的step_defination中,只需要用split(', ')就可以把字符串转化为Array了。

但是,如果你需要传递类似如下的数据呢?Array的元素是一个个hash。

Scenario Outline: invite friends
    When I am "<username>", I invite friends "<friends>" to join in the game
    Then My friends list has been updated
    Examples:
    | username | friends |
    |  Tom | [{:firstname=>"Tom", :lastname=>"Preston-Werner", :age => 20}, {:firstname=>"Kenneth", :lastname=>"Reitz", :age => 30}] |
    |  Lucy | [{:firstname=>"Tom", :lastname=>"Preston", :age => 19}]|

这时,example中需要传递类似[{:firstname=>"Tom", :lastname=>"Preston-Werner", :age => 20}, {:firstname=>"Kenneth", :lastname=>"Reitz", :age => 30}]的Array对象。

解决方法

鉴于Examples中只能传String,所以这里我们还是传String,同时借用下ruby中的Struct,最后将传递过来的string,转化成目标格式。

还是以上面的case为例,feature改成这样:

Scenario Outline: invite friends
    When I am "<username>", I invite friends "<friends>" to join in the game
    Then My friends list has been updated
    Examples:
    | username | friends |
    |  Tom | Tom, Preston-Werner, 20, Kenneth, Reitz, 30 |
    |  Lucy | Tom, Preston, 19|

这样问题就转化成,在对应的step_defination中,如何将字符串“Tom, Preston-Werner, 20, Kenneth, Reitz, 30” 转化成[{:firstname=>"Tom", :lastname=>"Preston-Werner", :age => 20}, {:firstname=>"Kenneth", :lastname=>"Reitz", :age => 30}]

用一个method来处理:

def transform_to_array(origin_arg)
  raise ArgumentError unless origin_arg.include?(',') ## 检查下参数
  friend = Struct.new(:firstname, :lastname, :age)
  [].tap do |result|
    origin_arg.split(', ').each_slice(3).to_a.each do |a|
      new_friend = friend.new(a.first,a[1], a.last )
      result << Hash[new_friend.each_pair.to_a]
    end
  end
end

OK!

参考

Struct

returning struct data as a hash in ruby