如何使用Capybara&测试多步骤表单最小测试? [英] How can I test multistep forms with Capybara & Minitest?
问题描述
我有一个单页Sinatra应用程序,该应用程序具有多步骤表单/向导界面.如果我想用水豚来测试表格,是否需要为每个测试重复所有步骤?我希望避免这样的事情:
I have a single page Sinatra app that has a multistep form/wizard interface. If I want to test the form with Capybara, will need to repeat all the steps for each test? I'm hoping to avoid something like this:
it "visits the home page" do
vist "/"
page.should have_content('foo')
end
it "clicks the first button" do
vist "/"
page.should have_content('foo')
button_click("Next")
end
it "clicks the second button" do
vist "/"
page.should have_content('foo')
button_click("Next")
page.should_have_content('bar')
end
it "clicks the third button" do
vist "/"
page.should have_content('foo')
button_click("Next")
page.should_have_content('bar')
button_click("Next")
end
I found an article about nested tests using RSpec and Capybara, but haven't been able to get a similar technique to work with Minitest.
推荐答案
我已经为您做过一些研究,并将与您分享我发现的内容.
I've done some research for you, and I'll share with you what I've found.
In order for doing this, you should consider "converting" your Minitest
tests, to specs. This gives you access for similar syntax, as RSpec
's - describe
with capability of nesting them.
我将简化代码以提供示例,但是应该清楚地将逻辑放在哪里.
我们来看几个例子.
1).让我们对Array
做一些简单的测试:
1). Let's do some simple test for Array
:
require "minitest/autorun"
describe Array do
before do
@arr = []
end
describe "when initialized" do
it "is empty" do
@arr.length.must_equal 0
end
end
end
这应该过去了,这里没有什么好看的.
This should pass, nothing really fancy here.
2).让我们添加另一个describe
,嵌套在我们拥有的describe
中:
2). Let's add another describe
, nested to one we have:
describe Array do
before do
@arr = []
end
describe "when initialized" do
it "is empty" do
@arr.length.must_equal 0
end
describe "when element added" do
it "length reflects the change" do
@arr << "a"
@arr.length.must_equal 1
end
end
end
end
这也有效-元素已添加到数组中,并且其length
指示正确.
This also works - an element has been added to the array, and its length
indicates that properly.
3).让我们尝试嵌套另一个块.我们希望保留@arr << "a"
,因此,如果添加另一个元素,@arr.length
将为2.让我们看看:
3). Let's try nesting another block. We're hoping, that @arr << "a"
will be preserved, so if we add another element, @arr.length
will be 2. Let's see:
describe Array do
before do
@arr = []
end
describe "when initialized" do
it "is empty" do
@arr.length.must_equal 0
end
describe "when element added" do
it "length reflects the change" do
@arr << "a"
@arr.length.must_equal 1
end
describe "when another element added" do
it "length also reflects the change" do
@arr << "b"
p @arr
@arr.length.must_equal 2
end
end
end
end
end
describe
嵌套在另一个describe
-中,就像我们对RSpec 所做的那样,但不幸的是,似乎@arr << "a"
的结果并未保留,并且嵌套的describe
的@arr.length
也是1.
describe
is nested within another describe
- as we would do for RSpec, but unfortunately, it seems that the result of @arr << "a"
is not preserved, and the nested describe
's @arr.length
is also 1.
我在代码中保留了p @arr
,因此您可以轻松地在控制台中查看@arr
中当前存储的内容.
I have left p @arr
in the code, so you can easily see in your console what is currently stored in @arr
.
绝对不是我们所期望的...让我们尝试一些疯狂然后...
Definitely not what we expected... Let's try something crazy then...
4).让我们将describe
嵌套在... it
:
4). Let's nest describe
within... it
:
describe Array do
before do
@arr = []
end
describe "when initialized" do
it "is empty" do
@arr.length.must_equal 0
end
describe "when element added" do
it "length reflects the change" do
@arr << "a"
@arr.length.must_equal 1
describe "when another element added" do
it "length also reflects the change" do
@arr << "b"
p @arr
@arr.length.must_equal 2
end
end
end
end
end
end
事实证明,这是完全有效的,并且其行为完全符合我们的预期! (再次,p @arr
留在这里,所以您可以在控制台中检查@arr
中当前存储的内容.)
Well, it turns out, that this is completely valid and it behaves exactly as we expected! (Again, p @arr
left here so you an check in console what is currently stored in @arr
).
老实说-我没有使用Capybara
进行检查,但是这个简单的示例很有希望.尝试相应地修改您的代码,以便在您的规范中实现Capybara
交互.
To be honest - I didn't check that with Capybara
, but this simple example is quite promising. Try modifying your code accordingly, so in your specs the Capybara
interactions are implemented.
让我清楚提供的解决方案:我再次强烈建议这种方法:
Let me be clear about provided solution: I strongly advise agains this approach:
- 这样的规范很难阅读,因此很难维护.
- 这被认为是错误的模式. 下一步步骤不应依赖上一步步骤的结果.
- Specs like this are difficult to read - and in result - difficult to maintain.
- This is considered bad pattern. Next steps should not rely on result of previous steps.
如果要正确测试控制器,则应尝试与此类似的操作(这是伪代码,仅用于说明想法):
If you want to test your contoller properly, you should try something similar to this (this is pseudo code just to illustrate idea):
测试步骤1
post "/url-to-my-form", { params_step_1: { ... } }
测试第2步
post "/url-to-my-form", { params_step_1: { ... }, params_step_2: { ... } }
使用这种方法很容易看到params
是什么,因此更易于测试例如.违反任何规则(空值,无效的电子邮件等).
With this approach is very easy to see what params
are post
ed, thus it's easier to test against eg. violations of any rules (empty values, invalid email, etc...).
希望有帮助!祝你好运!
Hope that helps! Good Luck!
这篇关于如何使用Capybara&测试多步骤表单最小测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!