如何使用 Capybara & Minitest 测试多步表单?
How can I test multistep forms with Capybara & Minitest?
我有一个具有多步骤 form/wizard 界面的单页 Sinatra 应用程序。如果我想用 Capybara 测试表格,是否需要为每个测试重复所有步骤?我希望避免这样的事情:
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
我找到了一篇关于 nested tests using RSpec and Capybara 的文章,但未能获得与 Minitest 一起使用的类似技术。
我已经为您做了一些调查,我将与您分享我的发现。
为此,您应该考虑 "converting" 您的 Minitest
测试到 specs。这使您可以访问类似的语法,如 RSpec
的 - describe
具有嵌套它们的能力。
我将简化代码以提供示例,但应该清楚将您的逻辑放在哪里。
让我们检查几个例子。
1).让我们对 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
这应该过去了,这里没什么特别的。
2).让我们添加另一个 describe
,嵌套到我们已有的一个:
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
表示正确。
3).让我们尝试嵌套另一个块。我们希望 @arr << "a"
将被保留,所以如果我们添加另一个元素,@arr.length
将为 2。让我们看看:
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.
我在代码中留下了 p @arr
,因此您可以在控制台中轻松查看当前存储在 @arr
中的内容。
绝对不是我们所期望的...让我们尝试一些疯狂 然后...
4).让我们将 describe
嵌套在... 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
中的内容)。
老实说 - 我没有用 Capybara
检查,但这个简单的例子很有前途。尝试相应地修改您的代码,以便在您的规范中实现 Capybara
交互。
让我明确提供的解决方案:我再次强烈建议这种方法:
- 像这样的规范很难阅读,因此也很难维护。
- 这被认为是错误的模式。 下一步 步骤不应 依赖于先前 步骤的结果。
如果你想正确地测试你的控制器,你应该尝试类似的东西(这是伪代码只是为了说明想法):
测试步骤 1
post "/url-to-my-form", { params_step_1: { ... } }
测试步骤 2
post "/url-to-my-form", { params_step_1: { ... }, params_step_2: { ... } }
使用这种方法很容易看出 params
是什么 post
ed,因此更容易针对 eg 进行测试。违反任何规则(空值、无效电子邮件等)。
希望对您有所帮助!祝你好运!
我有一个具有多步骤 form/wizard 界面的单页 Sinatra 应用程序。如果我想用 Capybara 测试表格,是否需要为每个测试重复所有步骤?我希望避免这样的事情:
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
我找到了一篇关于 nested tests using RSpec and Capybara 的文章,但未能获得与 Minitest 一起使用的类似技术。
我已经为您做了一些调查,我将与您分享我的发现。
为此,您应该考虑 "converting" 您的 Minitest
测试到 specs。这使您可以访问类似的语法,如 RSpec
的 - describe
具有嵌套它们的能力。
我将简化代码以提供示例,但应该清楚将您的逻辑放在哪里。
让我们检查几个例子。
1).让我们对 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
这应该过去了,这里没什么特别的。
2).让我们添加另一个 describe
,嵌套到我们已有的一个:
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
表示正确。
3).让我们尝试嵌套另一个块。我们希望 @arr << "a"
将被保留,所以如果我们添加另一个元素,@arr.length
将为 2。让我们看看:
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.
我在代码中留下了 p @arr
,因此您可以在控制台中轻松查看当前存储在 @arr
中的内容。
绝对不是我们所期望的...让我们尝试一些疯狂 然后...
4).让我们将 describe
嵌套在... 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
中的内容)。
老实说 - 我没有用 Capybara
检查,但这个简单的例子很有前途。尝试相应地修改您的代码,以便在您的规范中实现 Capybara
交互。
让我明确提供的解决方案:我再次强烈建议这种方法:
- 像这样的规范很难阅读,因此也很难维护。
- 这被认为是错误的模式。 下一步 步骤不应 依赖于先前 步骤的结果。
如果你想正确地测试你的控制器,你应该尝试类似的东西(这是伪代码只是为了说明想法):
测试步骤 1
post "/url-to-my-form", { params_step_1: { ... } }
测试步骤 2
post "/url-to-my-form", { params_step_1: { ... }, params_step_2: { ... } }
使用这种方法很容易看出 params
是什么 post
ed,因此更容易针对 eg 进行测试。违反任何规则(空值、无效电子邮件等)。
希望对您有所帮助!祝你好运!