【问题标题】:nested feature in capybara 2.0+capybara 2.0+ 中的嵌套功能
【发布时间】:2013-03-06 16:42:20
【问题描述】:

我想做这样的事情:

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

【问题讨论】:

    标签: ruby-on-rails-3 rspec capybara rspec-rails


    【解决方案1】:

    编辑(23/01/2014):嵌套功能从 2.2.1 版开始可用。见here

    编辑(2013 年 7 月 24 日): Capybara > 2.1.0 将允许嵌套功能。见here

    你不能。宝石管理员是这么说的

    我想你可以称之为限制。 feature 不能嵌套。 您可以改用contextdescribe,但我会 建议不要对这些疯狂,它往往会使测试变得漂亮 不可读。

    在某些其他情况下,可能会争论这样做的便利性,但在这个特定的情况下,您应该使用 scenario 而不是嵌套的 feature

    此外,如果您想在任何地方保持一致并使用新的 DSL,请使用 background 而不是 beforegiven 而不是 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。在那种情况下,我会这样做:

    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。也许是为了可读性,或者可能觉得不需要它,或者可能没有考虑过......如果你真的想嵌套功能,你可以随时尝试实现它并拉取请求。

    【讨论】:

    • 所以如果我必须的话,只需在功能描述中放入?
    • 不客气。如果它有效,那本身就是一件好事。除此之外,您应该尝试坚持良好的做法并找到您认为可读的一致风格。例如,对一种情况使用描述,对另一种情况使用场景是不一致的,也不可读。另一方面,我喜欢你如何在后台块中分离 fill_in 动作。但这一切也都是品味问题。 Here你可以找到一些推荐的rspec好实践,你可以看看并选择你想要遵循的。
    • 很好的链接!我在 describe 中添加了另一个场景,只是为了演示我对 describe 块的想法。它不是代替场景,而是能够将少量测试嵌套到共同的想法中(就像嵌套的描述块一样),是不是错了?
    • 这并没有错,因为您的规范通过了,但我个人认为混合使用两种 DSL 并不是很容易理解。如果我想深入嵌套规范,我只需使用describe/it。我再次使用旧 DSL 更新了我的答案。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多