RSpec 中是否有与 Cucumber 的“场景"等价的内容?还是我以错误的方式使用 RSpec? [英] Is there an equivalent in RSpec to Cucumber's "Scenarios" or am I using RSpec the wrong way?

查看:14
本文介绍了RSpec 中是否有与 Cucumber 的“场景"等价的内容?还是我以错误的方式使用 RSpec?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Cucumber 场景的简洁性和实用性给我留下了深刻的印象,它们是测试大量不同案例的好方法.

例如Cucumber 场景示例

功能:管理用户为了管理用户详细信息作为一名安全爱好者我只想在授权时编辑用户配置文件场景大纲:显示或隐藏编辑配置文件链接鉴于以下用户记录|用户名 |密码 |管理员 ||鲍勃 |秘密|假 ||管理员 |秘密|真实 |鉴于我以<login>"身份登录用密码秘密"当我访问<profile>"的个人资料时那我应该<行动>例子:|登录 |简介 |行动 ||管理员 |鲍勃 |见编辑个人资料" ||鲍勃 |鲍勃 |见编辑个人资料" |||鲍勃 |看不到编辑个人资料"||鲍勃 |管理员 |看不到编辑个人资料"|

(代码取自 Ryan Bates' More on Cucumber Screencast)p>

RSpec 中是否有等价物?

我想在 RSpec 中做同样的事情,并通过将不同的测试减少到场景表中的一行来干燥我的代码.

虽然我可以自己编写代码来执行此操作,但我正在考虑这样做的事实让我想知道两件事

  1. 如果这很有用,它可能已经存在,在这种情况下我该如何使用它?

  2. 如果它不存在,则表明不应该这样做,并且我处理问题的方法不正确,我应该如何重新考虑我的 RSpec 方法?

哪个答案是正确的,如果有用,我该怎么做?

解决方案

试试下面的方法.我喜欢它的结果.

describe StateDateMethods 做之前:每个都做@product = OpenStruct.new@product.extend StateDateMethods结尾def parse_date(unparsed_date_value)除非 unparsed_date_value.nil?DateTime.strptime(unparsed_date_value, '%m/%d/%Y')结尾结尾上下文'#pre_order?做例子= [# [visible_on, pre_order_on, for_sale_on] =>方法结果{ :输入 =>[nil, nil, nil], :expected =>错误的 },{ :输入 =>['1/1/2001', nil, nil], :expected =>错误的 },{ :输入 =>['1/1/2001', '1/1/2001', nil], :expected =>真的 },{ :输入 =>['1/1/2001', '1/2/2001', nil], :expected =>真的 },{ :输入 =>['1/1/2001', '1/1/2001', '1/2/2001'], :expected =>错误的 },{ :输入 =>['1/1/2001', '1/1/2001', '1/1/3001'], :expected =>真的 },{ :输入 =>['1/1/2001', '1/1/3001', '1/2/3001'], :expected =>错误的 },{ :输入 =>['1/1/3001', '1/1/3001', '1/2/3001'], :expected =>错误的 },{ :输入 =>['1/1/2001', nil, '1/1/2001'], :expected =>错误的 },{ :输入 =>['1/1/2001', nil, '1/1/3001'], :expected =>错误的 }]examples.each 做 |example|输入 = 示例 [:输入]它应该在 visible_on == #{inputs[0].inspect}, pre_order_on == #{inputs[1].inspect}, for_sale_on == #{inputs[2] 时返回 #{example[:expected].inspect}.inspect}" 做@product.visible_on = parse_date(输入[0])@product.pre_order_on = parse_date(输入[1])@product.for_sale_on = parse_date(输入[2])@product.pre_order?.should == 例子[:expected]结尾结尾结尾结尾

我认为这提供了两全其美的效果,因为它可以防止我重复自己,并且它为每种情况创建了不同的测试.

下面是失败的样子:

....F.......失败:1)StateDateMethods#pre_order?当 visible_on == "1/1/2001", pre_order_on == "1/1/2001", for_sale_on == "1/2/2001" 时应该返回 false失败/错误:@product.pre_order?.should == example[:expected]预期:假得到:真(使用==)# ./spec_no_rails/state_date_methods_spec.rb:40:in `block (4 levels) in <top (required)>'在 0.38933 秒内完成10 个例子,1 个失败失败的例子:rspec ./spec_no_rails/state_date_methods_spec.rb:35 # StateDateMethods#pre_order?当 visible_on == "1/1/2001", pre_order_on == "1/1/2001", for_sale_on == "1/2/2001" 时应该返回 false

这就是所有绿色的样子:

<代码>.......在 0.3889 秒内完成10 个示例,0 次失败

I'm impressed at the brevity and usefulness of Cucumber's Scenarios, they're a great way to test a load of different cases.

e.g. example Cucumber scenario

Feature: Manage Users
In order to manage user details
As a security enthusiast
I want to edit user profiles only when authorized

Scenario Outline: Show or hide edit profile link
  Given the following user records
    | username | password | admin |
    | bob      | secret   | false |
    | admin    | secret   | true  |
  Given I am logged in as "<login>" with password "secret"
  When I visit profile for "<profile>"
  Then I should <action>

  Examples:
    | login | profile | action                 |
    | admin | bob     | see "Edit Profile"     |
    | bob   | bob     | see "Edit Profile"     |
    |       | bob     | not see "Edit Profile" |
    | bob   | admin   | not see "Edit Profile" |

(Code taken from Ryan Bates' More on Cucumber Screencast)

Is there an equivalent in RSpec?

I'd like to do the same thing in RSpec and to DRY up my code by reducing different tests down to a row in a scenario table.

Although I could write the code to do this myself, the fact that I'm considering it makes me wonder two things

  1. If this is useful it probably already exists in which case how do I use it?

  2. If it doesn't exist it suggests it shouldn't be done this way and that I'm approaching the problem incorrectly, how should I rethink my approach to RSpec?

Which answer is right and if it is useful, how do I do it?

解决方案

Try the following approach. I like the way it turned out.

describe StateDateMethods do
  before :each do
    @product = OpenStruct.new
    @product.extend StateDateMethods
  end

  def parse_date(unparsed_date_value)
    unless unparsed_date_value.nil?
      DateTime.strptime(unparsed_date_value, '%m/%d/%Y')
    end
  end

  context '#pre_order?' do
    examples = [
      # [visible_on, pre_order_on, for_sale_on] => method_result
      { :inputs => [nil, nil, nil], :expected => false },
      { :inputs => ['1/1/2001', nil, nil], :expected => false },
      { :inputs => ['1/1/2001', '1/1/2001', nil], :expected => true },
      { :inputs => ['1/1/2001', '1/2/2001', nil], :expected => true },
      { :inputs => ['1/1/2001', '1/1/2001', '1/2/2001'], :expected => false },
      { :inputs => ['1/1/2001', '1/1/2001', '1/1/3001'], :expected => true },
      { :inputs => ['1/1/2001', '1/1/3001', '1/2/3001'], :expected => false },
      { :inputs => ['1/1/3001', '1/1/3001', '1/2/3001'], :expected => false },
      { :inputs => ['1/1/2001', nil, '1/1/2001'], :expected => false },
      { :inputs => ['1/1/2001', nil, '1/1/3001'], :expected => false }
    ]
    examples.each do |example|
      inputs = example[:inputs]

      it "should return #{example[:expected].inspect} when visible_on == #{inputs[0].inspect}, pre_order_on == #{inputs[1].inspect}, for_sale_on == #{inputs[2].inspect}" do
        @product.visible_on = parse_date(inputs[0])
        @product.pre_order_on = parse_date(inputs[1])
        @product.for_sale_on = parse_date(inputs[2])

        @product.pre_order?.should == example[:expected]
      end
    end
  end
end

I think this gives the best of both worlds, because it keeps me from repeating myself, and it creates a different test for each condition.

Here's what a failure looks like:

....F.....

Failures:

  1) StateDateMethods#pre_order? should return false when visible_on == "1/1/2001", pre_order_on == "1/1/2001", for_sale_on == "1/2/2001"
     Failure/Error: @product.pre_order?.should == example[:expected]
       expected: false
            got: true (using ==)
     # ./spec_no_rails/state_date_methods_spec.rb:40:in `block (4 levels) in <top (required)>'

Finished in 0.38933 seconds
10 examples, 1 failure

Failed examples:

rspec ./spec_no_rails/state_date_methods_spec.rb:35 # StateDateMethods#pre_order? should return false when visible_on == "1/1/2001", pre_order_on == "1/1/2001", for_sale_on == "1/2/2001"

And here's what all green looks like:

..........

Finished in 0.3889 seconds
10 examples, 0 failures

这篇关于RSpec 中是否有与 Cucumber 的“场景"等价的内容?还是我以错误的方式使用 RSpec?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆