Ruby on rails RSpec中是否有与Cucumber';s";情景“;还是我使用RSpec的方式不对?
Cucumber场景的简洁性和实用性给我留下了深刻的印象,它们是测试大量不同案例的好方法 例如黄瓜场景示例Ruby on rails RSpec中是否有与Cucumber';s";情景“;还是我使用RSpec的方式不对?,ruby-on-rails,rspec,cucumber,Ruby On Rails,Rspec,Cucumber,Cucumber场景的简洁性和实用性给我留下了深刻的印象,它们是测试大量不同案例的好方法 例如黄瓜场景示例 功能:管理用户 以管理用户详细信息 作为一个安全爱好者 我只想在授权后编辑用户配置文件 场景大纲:显示或隐藏编辑配置文件链接 给定以下用户记录 |用户名|密码|管理员| |鲍勃|秘密|假| |管理员|秘密|真实| 假设我以“”身份登录,密码为“secret” 当我访问“”的配置文件时 那么我应该) RSpec中是否有等效项? 我想在RSpec中做同样的事情,并通过将不同的测试减少到场景表中
功能:管理用户
以管理用户详细信息
作为一个安全爱好者
我只想在授权后编辑用户配置文件
场景大纲:显示或隐藏编辑配置文件链接
给定以下用户记录
|用户名|密码|管理员|
|鲍勃|秘密|假|
|管理员|秘密|真实|
假设我以“”身份登录,密码为“secret”
当我访问“”的配置文件时
那么我应该)
RSpec中是否有等效项?
我想在RSpec中做同样的事情,并通过将不同的测试减少到场景表中的一行来干涸我的代码
虽然我可以自己编写代码来实现这一点,但事实上我正在考虑这一点,这让我想知道两件事
如果这是有用的,它可能已经存在,在这种情况下,我该如何使用它
如果它不存在,它表明不应该这样做,并且我处理问题的方法不正确,我应该如何重新思考我的RSpec方法
哪个答案是正确的,如果有用,我该怎么做?我不会以这种方式使用RSpec。RSpec应该用于将行为一次驱动到一类小行为中。因为每个行为都是唯一的,所以应该使用不同的规范来定义它
在上述场景中,您可能有指定行为的规范,如:
it "should allow user to edit his own profile"
it "should allow admin to edit other users profile"
it "should not allow non-admin to edit admin profile"
it "should not allow anonymous user to edit any profile"
还有一件事,使用RSpec驱动应用程序的多个层不是一个好主意。换句话说,在定义控制器时,应该模拟与模型的交互等。我在问题中给出了一个适合RSpec的示例。我给出了一个可能的解决方案,但如果您找到更好的,请告诉我。尝试以下方法。我喜欢结果的样子
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
我认为这两个方面都是最好的,因为它让我避免重复我自己,并且它为每种情况创建了不同的测试
以下是失败的样子:
....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"
..........
Finished in 0.3889 seconds
10 examples, 0 failures
对于使用RSpec进行的表驱动/参数化测试,现在有几个GEM可能会有所帮助:
- -用于参数化测试的微型DSL(披露:我是作者)
- -支持RSpec中的简单参数化测试语法
你好,cheezy,谢谢你。虽然我使用的是cucumber中的集成测试示例,但我确实知道(尽管我并不总是能够做到)RSpec应该使用的粒度。我的问题不是关于那个特定的规范,而是关于表驱动场景的想法。你知道RSpec是否支持这一点吗?我还没有看到在RSpec中提供表的gem。同样,我想不出一个合适的例子。同样,有一个gem在rspec中提供了给定的/When/Then关键字,我一直在使用它。我在问题中给出的例子怎么样?尽管RSpec通常用于单元测试级别(一次一个类),但它也可以用于构建与cumber工作在同一级别的集成测试。当不需要与非技术利益相关者共享验收标准时,这有时是一种可接受的方法。回答得很好。这让人想起Specs2的数据表。
..........
Finished in 0.3889 seconds
10 examples, 0 failures