I have a page which either returns "No match." or one of the model objects names.
What is the best way to test it with Cucumber? Should I stub rand in Given
step or should I provide something like page has either a or b
? Or maybe I should provide rand
parameters in scenarion outline parameter, use this parameter in Given
step and use the second outline column to check the result?
我有一个页面要么返回“不匹配”。或其中一个模型对象名称。用Cucumber测试它的最佳方法是什么?我应该在给定步骤中存根rand还是应该提供像页面有a或b的东西?或者我可以在scenarion outline参数中提供rand参数,在Given步骤中使用此参数并使用第二个outline列来检查结果?
UPDATE: cookies
controller example in the best traditions of Cookie Monster:
更新:饼干怪物的最佳传统中的cookie控制器示例:
cookie_controller.rb
cookie_controller.rb
def random_cookie
if rand(5) == 0 do
cookie = Cookie.offset(rand(Cookie.count)).first
response = "You got 10 free #{cookie.type} cookies for your purchase!"
else
response = "Sorry, no cookies left :'("
end
respond_to do |format|
format.json { render json: { response: response } }
end
find_cookie.feature
find_cookie.feature
Scenario: Looking for cookie
When I click "find"
Then I should see "You got 10 free" or "Sorry, no cookies left :'("
How would Then I should see "You got 10 free" or "Sorry, no cookies left :'("
step look? I've tried something like
怎么会那么我应该看到“你有10个免费”或“对不起,没有剩下的饼干:”(“一步看?我试过像
(page.should have_content "You got 10 free") || (page.should have_content "Sorry, no cookies left :'("
But it didn't work.
但它没有用。
3 个解决方案
#1
2
One of the properties of tests is that they should be repeatable: they should produce the same results each time, every time. Tests should not rely in uncontrollable params (like external resources, or random sources).
测试的一个属性是它们应该是可重复的:它们每次都应该产生相同的结果。测试不应该依赖于无法控制的参数(如外部资源或随机源)。
My point is that you will need two tests, one that checks for “You got 10 free” and another one that checks “Sorry, no cookies left”.
我的观点是你需要进行两次测试,一次检查“你有10个免费”,另一个检查“对不起,没有剩下的cookie”。
In the documentation of rand
, you can find this snippet: “Kernel::srand
may be used to ensure repeatable sequences of random numbers between different runs of the program.”, so if your write your scenarios with a setup step that sets the seed to some number that you know results (always) in one result or the other you will have your tests.
在rand的文档中,您可以找到以下片段:“Kernel :: srand可用于确保程序的不同运行之间的可重复序列的随机数。”,所以如果您使用设置步骤设置种子来编写场景某个数字,你知道结果(总是)在一个结果或另一个结果,你将有你的测试。
Scenario: Looking for cookie and finding it
When I seed with X
And click "find"
Then I should see "You got 10 free"
Scenario: Looking for cookie and not finding it
When I seed with Y
And click "find"
Then I should see "Sorry, no cookies left :'("
When /^I seed with (\d+)$/ do |seed|
srand(seed.to_i)
end
You will need to find which seeds give you one result or the other, but once you find them, they will work forever.
你将需要找到哪种种子给你一个结果或另一个结果,但一旦你找到它们,它们将永远地工作。
#2
1
Don't test random behaviour as this goes against proper software design practices. Your tests should be deterministic.
不要测试随机行为,因为这违反了正确的软件设计实践。您的测试应该是确定性的。
A way to wrest control of this is to define a module or class that can be substituted or mocked as required:
取而决制的方法是定义一个可以根据需要替换或模拟的模块或类:
def random_cookie
if CookieDealer.free_cookie?
# ...
end
end
The method would look like:
该方法看起来像:
require 'securerandom'
module CookieDealer
def self.free_cookie?
SecureRandom.random_number(5) == 0
end
end
You can then mock the free_cookie?
method to simulate various conditions.
你可以嘲笑free_cookie吗?模拟各种条件的方法。
You will, of course, want to test the free_cookies
method itself in a unit test of some sort. In this case you might want to run a very large number of tests to be sure it hands out approximately the correct number of cookies.
当然,您将要在某种单元测试中测试free_cookies方法本身。在这种情况下,您可能希望运行大量测试,以确保它能够分发大约正确数量的cookie。
#3
0
You will want to set the random seed, perhaps storing the original to restore it after testing is done.
您将需要设置随机种子,可能存储原始文件以在测试完成后恢复它。
See documentation here: http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-srand for 1.9.3 or documentation for Ruby 2.0.0 here: http://ruby-doc.org/core-2.0/Kernel.html#method-i-srand
请参阅此处的文档:http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-srand for 1.9.3或Ruby 2.0.0的文档:http:// ruby-doc。组织/芯 - 2.0 / Kernel.html#方法-I-函数srand
#1
2
One of the properties of tests is that they should be repeatable: they should produce the same results each time, every time. Tests should not rely in uncontrollable params (like external resources, or random sources).
测试的一个属性是它们应该是可重复的:它们每次都应该产生相同的结果。测试不应该依赖于无法控制的参数(如外部资源或随机源)。
My point is that you will need two tests, one that checks for “You got 10 free” and another one that checks “Sorry, no cookies left”.
我的观点是你需要进行两次测试,一次检查“你有10个免费”,另一个检查“对不起,没有剩下的cookie”。
In the documentation of rand
, you can find this snippet: “Kernel::srand
may be used to ensure repeatable sequences of random numbers between different runs of the program.”, so if your write your scenarios with a setup step that sets the seed to some number that you know results (always) in one result or the other you will have your tests.
在rand的文档中,您可以找到以下片段:“Kernel :: srand可用于确保程序的不同运行之间的可重复序列的随机数。”,所以如果您使用设置步骤设置种子来编写场景某个数字,你知道结果(总是)在一个结果或另一个结果,你将有你的测试。
Scenario: Looking for cookie and finding it
When I seed with X
And click "find"
Then I should see "You got 10 free"
Scenario: Looking for cookie and not finding it
When I seed with Y
And click "find"
Then I should see "Sorry, no cookies left :'("
When /^I seed with (\d+)$/ do |seed|
srand(seed.to_i)
end
You will need to find which seeds give you one result or the other, but once you find them, they will work forever.
你将需要找到哪种种子给你一个结果或另一个结果,但一旦你找到它们,它们将永远地工作。
#2
1
Don't test random behaviour as this goes against proper software design practices. Your tests should be deterministic.
不要测试随机行为,因为这违反了正确的软件设计实践。您的测试应该是确定性的。
A way to wrest control of this is to define a module or class that can be substituted or mocked as required:
取而决制的方法是定义一个可以根据需要替换或模拟的模块或类:
def random_cookie
if CookieDealer.free_cookie?
# ...
end
end
The method would look like:
该方法看起来像:
require 'securerandom'
module CookieDealer
def self.free_cookie?
SecureRandom.random_number(5) == 0
end
end
You can then mock the free_cookie?
method to simulate various conditions.
你可以嘲笑free_cookie吗?模拟各种条件的方法。
You will, of course, want to test the free_cookies
method itself in a unit test of some sort. In this case you might want to run a very large number of tests to be sure it hands out approximately the correct number of cookies.
当然,您将要在某种单元测试中测试free_cookies方法本身。在这种情况下,您可能希望运行大量测试,以确保它能够分发大约正确数量的cookie。
#3
0
You will want to set the random seed, perhaps storing the original to restore it after testing is done.
您将需要设置随机种子,可能存储原始文件以在测试完成后恢复它。
See documentation here: http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-srand for 1.9.3 or documentation for Ruby 2.0.0 here: http://ruby-doc.org/core-2.0/Kernel.html#method-i-srand
请参阅此处的文档:http://ruby-doc.org/core-1.9.3/Kernel.html#method-i-srand for 1.9.3或Ruby 2.0.0的文档:http:// ruby-doc。组织/芯 - 2.0 / Kernel.html#方法-I-函数srand