我想这样做:
feature "sign-up" do
before {visit signup_path}
let(:submit) {"Create my account"}
feature "with invalid information" do
scenario "should not create a user" do
expect {click_button submit}.not_to change(User, :count)
end
end
feature "with valid information" do
scenario "should create a user" do
fill_in "Name", with: "test name"
fill_in "Email", with: "test@test.com"
fill_in "Password", with: "password"
fill_in "Confirmation", with: "password"
expect {click_button submit}.to change(User, :count).by(1)
end
end
end
但是当我运行rspec时,我得到
in `block in <top (required)>': undefined method `feature' for #<Class:0x000000039e0018> (NoMethodError)
如果我稍微改变一下,看起来像这样,它可以工作:
feature "with invalid information" do
before {visit signup_path}
let(:submit) {"Create my account"}
scenario "should not create a user" do
expect {click_button submit}.not_to change(User, :count)
end
end
feature "with valid information" do
before {visit signup_path}
let(:submit) {"Create my account"}
scenario "should create a user" do
fill_in "Name", with: "test name"
fill_in "Email", with: "test@test.com"
fill_in "Password", with: "nirnir"
fill_in "Confirmation", with: "nirnir"
expect {click_button submit}.to change(User, :count).by(1)
end
end
编辑:加上,下面的代码可以工作(描述嵌套的内部特性)-但是它在任何方面都是错误的吗?
feature "sign-up" do
background {visit signup_path}
given(:submit) {"Create my account"}
scenario "with invalid information" do
expect {click_button submit}.not_to change(User, :count)
end
describe "with valid information" do
background do
fill_in "Name", with: "test name"
fill_in "Email", with: "test@test.com"
fill_in "Password", with: "password"
fill_in "Confirmation", with: "password"
end
scenario { expect {click_button submit}.to change(User, :count).by(1) }
scenario "after submission" do
click_button submit
page.html.should have_content("Registration successful")
end
end
end
EDIT (23/01/2014):嵌套功能自2.2.1版本起可用。看到
EDIT (24/07/2013):嵌套功能将在Capybara> 2.1.0中被允许。看到
你不能。这是gem的维护者说的
我想你可以把这叫做限制。
feature
不能嵌套。你可以用context
或者describe
来代替,但是我会建议不要过度使用这些内容,这会使测试变得很漂亮不可读。
在其他一些情况下,可能会争论这样做的便利性,但在这个特定的情况下,您应该使用scenario
而不是嵌套的feature
。
同样,如果你想保持一致并在任何地方使用新的DSL,请使用background
代替before
,使用given
代替let
。这样的:
feature "sign-up" do
background {visit signup_path}
given(:submit) {"Create my account"}
scenario "with invalid information" do
expect {click_button submit}.not_to change(User, :count)
end
scenario "with valid information" do
fill_in "Name", with: "test name"
fill_in "Email", with: "test@test.com"
fill_in "Password", with: "password"
fill_in "Confirmation", with: "password"
expect {click_button submit}.to change(User, :count).by(1)
end
end
你必须删除it
,因为scenario
只是it
的别名,你也不能嵌套it
。
如果你觉得旧的DSL可读性更好,你也可以随时切换回旧的DSL。在这种情况下,我会这样做:
describe "sign-up" do
before {visit signup_path}
let(:submit) {"Create my account"}
context "with invalid information" do
it "does not create a user" do
expect {click_button submit}.not_to change(User, :count)
end
end
context "with valid information" do
before
fill_in "Name", with: "test name"
fill_in "Email", with: "test@test.com"
fill_in "Password", with: "password"
fill_in "Confirmation", with: "password"
end
it "creates a user" do
expect {click_button submit}.to change(User, :count).by(1)
end
end
end
但是只要规范检查了它必须检查的东西,你就应该没事。其余的都是风格、可读性和良好实践的问题,这些都很重要,但更容易引起讨论和分歧。在这种情况下,gem的作者不允许嵌套feature
,可能是为了可读性,也可能是觉得不需要,也可能是没有想过……如果你真的想嵌套功能,你可以尝试实现它并拉取请求。