【问题标题】:rspec/factory issues from hartl chapter 9.2 - app functions fine, but tests are failing来自 hartl 第 9.2 章的 rspec/factory 问题 - 应用程序功能正常,但测试失败
【发布时间】:2013-03-28 22:41:42
【问题描述】:

在我对 Hartl 教程的section 9.2 中的 rspec 测试进行最后一次更改之前,所有测试都运行良好。那时我的 user_pages_spec.rb 和 application_pages_spec.rb 中的所有相关测试都失败了。

虽然我已经检查了该网站,但故障并未在现实生活中出现 - 所以我认为这是测试套件试图模拟用户的方式的问题 - 这是有道理的,因为这就是我所做的更改。

有一点需要注意 - 我已经对 Hartl 教程进行了一些调整,但大多数都是装饰性的或次要的 - 这里唯一可能重要的是我使用用户名而不是电子邮件进行登录和查找。

完整文件如下 - 非常感谢任何帮助,因为我已经把头撞在墙上几个小时了,而且它变得非常令人沮丧。

spec/support/utilities.rb:

def full_title(page_title)
  base_title = "nsent"
  if page_title.empty?
    base_title
  else
    "#{base_title} | #{page_title}"
  end
end

def sign_in(user)
  visit signin_path
  fill_in "Name",    with: user.name
  fill_in "Password", with: user.password
  click_button "Sign in"
  # Sign in when not using Capybara as well.
  cookies[:remember_token] = user.remember_token
end

spec/support/factories.rb:

FactoryGirl.define do
  factory :user do
    name     "Example User"
    email    "user@example.com"
    password "foobar"
    password_confirmation "foobar"
  end
end

user_pages_spec.rb:

require 'spec_helper'

describe "User pages" do

  subject { page }

  describe "signup" do

    before { visit signup_path }

    describe "should have the right title and heading" do
            it { should have_selector('h1',    text: "Sign up") }
        it { should have_selector('title', text: full_title("Sign up")) }
    end

    let(:submit) { "Sign up" }

    describe "with invalid information" do
      it "should not create a user" do
        expect { click_button submit }.not_to change(User, :count)
      end
      describe "after submission" do
        before {click_button submit }

        it { should have_selector('title', text: "Sign up") }
        it { should have_content('field') }
      end
    end

    describe "with valid information" do
      before do
        fill_in "Name",         with: "Example User"
        fill_in "Email",        with: "user@example.com"
        fill_in "Password",     with: "foobar"
        fill_in "Password confirmation", with: "foobar"
      end

      it "should create a user" do
        expect { click_button submit }.to change(User, :count).by(1)
      end

      describe "after saving the user" do
        before { click_button submit }
        let(:user) { User.find_by_email('user@example.com') }

        it { should have_selector('title', text: user.name) }
        it { should have_selector('div.alert.alert-success', text: 'welcome') }
        it { should have_link('Sign out') }
      end
        end
  end

    describe "profile page" do
      let(:user) { FactoryGirl.create(:user) }
      before { visit user_path(user) }

      it { should have_selector('h1',    text: user.name) }
      it { should have_selector('title', text: user.name) }
    end

  describe "edit" do
    let(:user) { FactoryGirl.create(:user) }
    before do
      sign_in user
      visit edit_user_path(user)
    end

    describe "page" do
      it { should have_selector('h1',    text: "Update your profile") }
      it { should have_selector('title', text: "Edit user") }
      it { should have_link('Change Profile Picture', href: 'http://gravatar.com/emails') }
    end

    describe "with invalid information" do
      before { click_button "Save changes" }

      it { should have_content('Whoops') }
    end

    describe "with valid information" do
      let(:new_name)  { "New Name" }
      let(:new_email) { "new@example.com" }
      before do
        fill_in "Name",             with: new_name
        fill_in "Password",         with: user.password
        fill_in "Password confirmation", with: user.password
        fill_in "Email",            with: new_email
        click_button "Save changes"
      end

      it { should have_selector('title', text: new_name) }
      it { should have_selector('div.alert.alert-success') }
      it { should have_link('Sign out', href: signout_path) }
      specify { user.reload.name.should  == new_name }
      specify { user.reload.email.should == new_email }
    end
  end
end

user_pages_spec.rb 失败(终端输出):

    Failures:

  1) User pages edit with invalid information
     Failure/Error: before { click_button "Save changes" }
     Capybara::ElementNotFound:
       no button with value or id or text 'Save changes' found
     # (eval):2:in `click_button'
     # ./spec/requests/user_pages_spec.rb:75:in `block (4 levels) in <top (required)>'

  2) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  3) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  4) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  5) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  6) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  7) User pages edit page
     Failure/Error: it { should have_selector('title', text: "Edit user") }
       expected css "title" with text "Edit user" to return something
     # ./spec/requests/user_pages_spec.rb:70:in `block (4 levels) in <top (required)>'

  8) User pages edit page
     Failure/Error: it { should have_link('Change Profile Picture', href: 'http://gravatar.com/emails') }
       expected link "Change Profile Picture" to return something
     # ./spec/requests/user_pages_spec.rb:71:in `block (4 levels) in <top (required)>'

  9) User pages edit page
     Failure/Error: it { should have_selector('h1',    text: "Update your profile") }
       expected css "h1" with text "Update your profile" to return something
     # ./spec/requests/user_pages_spec.rb:69:in `block (4 levels) in <top (required)>'

Finished in 1.06 seconds
20 examples, 9 failures

Failed examples:

rspec ./spec/requests/user_pages_spec.rb:77 # User pages edit with invalid information
rspec ./spec/requests/user_pages_spec.rb:91 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:93 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:92 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:95 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:94 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:70 # User pages edit page
rspec ./spec/requests/user_pages_spec.rb:71 # User pages edit page
rspec ./spec/requests/user_pages_spec.rb:69 # User pages edit page

application_pages_spec.rb:

require 'spec_helper'

describe "Authentication" do

  subject { page }

  describe "signin page" do
    before { visit signin_path }

    it { should have_selector('h1',    text: 'Sign in') }
    it { should have_selector('title', text: 'Sign in') }
  end

  describe "signin" do
    before { visit signin_path }

    describe "with invalid information" do
      before { click_button "Sign in" }

      it { should have_selector('title', text: 'Sign in') }
      it { should have_selector('div.alert.alert-error', text: 'Invalid') }

      describe "after visiting another page" do
        before { click_link "nsent"}
        it { should_not have_selector('div.alert.alert-error') }
      end
    end

    describe "with valid information" do
      let(:user) { FactoryGirl.create(:user) }
      before { sign_in user }

      it { should have_selector('title', text: user.name) }
      it { should have_link('Profile',  href: user_path(user)) }
      it { should have_link('Settings', href: edit_user_path(user)) }
      it { should have_link('Sign out', href: signout_path) }
      it { should_not have_link('Sign in', href: signin_path) }

      describe "followed by signout" do
        before { click_link "Sign out" }
        it { should have_link('Sign in', href: signin_path) }
        it { should_not have_link('Profile',  href: user_path(user)) }
        it { should_not have_link('Settings', href: edit_user_path(user)) }
        it { should_not have_link('Sign out', href: signout_path) }
      end
    end
  end

    describe "authorization" do

    describe "for non-signed-in users" do
      let(:user) { FactoryGirl.create(:user) }

      describe "in the Users controller" do

        describe "visiting the edit page" do
          before { visit edit_user_path(user) }
          it { should have_selector('title', text: 'Sign in') }
        end

        describe "submitting to the update action" do
          before { put user_path(user) }
          specify { response.should redirect_to(signin_path) }
        end
      end
    end
  end
end

applications_pages_spec.rb 失败(终端输出):

Failures:

  1) Authentication signin with valid information
     Failure/Error: it { should have_selector('title', text: user.name) }
       expected css "title" with text "Example User" to return something
     # ./spec/requests/authentication_pages_spec.rb:33:in `block (4 levels) in <top (required)>'

  2) Authentication signin with valid information
     Failure/Error: it { should have_link('Settings', href: edit_user_path(user)) }
       expected link "Settings" to return something
     # ./spec/requests/authentication_pages_spec.rb:35:in `block (4 levels) in <top (required)>'

  3) Authentication signin with valid information
     Failure/Error: it { should have_link('Profile',  href: user_path(user)) }
       expected link "Profile" to return something
     # ./spec/requests/authentication_pages_spec.rb:34:in `block (4 levels) in <top (required)>'

  4) Authentication signin with valid information
     Failure/Error: it { should_not have_link('Sign in', href: signin_path) }
       expected link "Sign in" not to return anything
     # ./spec/requests/authentication_pages_spec.rb:37:in `block (4 levels) in <top (required)>'

  5) Authentication signin with valid information
     Failure/Error: it { should have_link('Sign out', href: signout_path) }
       expected link "Sign out" to return something
     # ./spec/requests/authentication_pages_spec.rb:36:in `block (4 levels) in <top (required)>'

  6) Authentication signin with valid information followed by signout
     Failure/Error: before { click_link "Sign out" }
     Capybara::ElementNotFound:
       no link with title, id or text 'Sign out' found
     # (eval):2:in `click_link'
     # ./spec/requests/authentication_pages_spec.rb:40:in `block (5 levels) in <top (required)>'

  7) Authentication signin with valid information followed by signout
     Failure/Error: before { click_link "Sign out" }
     Capybara::ElementNotFound:
       no link with title, id or text 'Sign out' found
     # (eval):2:in `click_link'
     # ./spec/requests/authentication_pages_spec.rb:40:in `block (5 levels) in <top (required)>'

  8) Authentication signin with valid information followed by signout
     Failure/Error: before { click_link "Sign out" }
     Capybara::ElementNotFound:
       no link with title, id or text 'Sign out' found
     # (eval):2:in `click_link'
     # ./spec/requests/authentication_pages_spec.rb:40:in `block (5 levels) in <top (required)>'

  9) Authentication signin with valid information followed by signout
     Failure/Error: before { click_link "Sign out" }
     Capybara::ElementNotFound:
       no link with title, id or text 'Sign out' found
     # (eval):2:in `click_link'
     # ./spec/requests/authentication_pages_spec.rb:40:in `block (5 levels) in <top (required)>'

  10) User pages edit with invalid information
     Failure/Error: before { click_button "Save changes" }
     Capybara::ElementNotFound:
       no button with value or id or text 'Save changes' found
     # (eval):2:in `click_button'
     # ./spec/requests/user_pages_spec.rb:75:in `block (4 levels) in <top (required)>'

  11) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  12) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  13) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  14) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  15) User pages edit with valid information
     Failure/Error: fill_in "Password confirmation", with: user.password
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Password confirmation' found
     # (eval):2:in `fill_in'
     # ./spec/requests/user_pages_spec.rb:86:in `block (4 levels) in <top (required)>'

  16) User pages edit page
     Failure/Error: it { should have_selector('title', text: "Edit user") }
       expected css "title" with text "Edit user" to return something
     # ./spec/requests/user_pages_spec.rb:70:in `block (4 levels) in <top (required)>'

  17) User pages edit page
     Failure/Error: it { should have_link('Change Profile Picture', href: 'http://gravatar.com/emails') }
       expected link "Change Profile Picture" to return something
     # ./spec/requests/user_pages_spec.rb:71:in `block (4 levels) in <top (required)>'

  18) User pages edit page
     Failure/Error: it { should have_selector('h1',    text: "Update your profile") }
       expected css "h1" with text "Update your profile" to return something
     # ./spec/requests/user_pages_spec.rb:69:in `block (4 levels) in <top (required)>'

Finished in 1.53 seconds
36 examples, 18 failures

Failed examples:

rspec ./spec/requests/authentication_pages_spec.rb:33 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:35 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:34 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:37 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:36 # Authentication signin with valid information
rspec ./spec/requests/authentication_pages_spec.rb:42 # Authentication signin with valid information followed by signout
rspec ./spec/requests/authentication_pages_spec.rb:44 # Authentication signin with valid information followed by signout
rspec ./spec/requests/authentication_pages_spec.rb:41 # Authentication signin with valid information followed by signout
rspec ./spec/requests/authentication_pages_spec.rb:43 # Authentication signin with valid information followed by signout
rspec ./spec/requests/user_pages_spec.rb:77 # User pages edit with invalid information
rspec ./spec/requests/user_pages_spec.rb:91 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:93 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:92 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:95 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:94 # User pages edit with valid information
rspec ./spec/requests/user_pages_spec.rb:70 # User pages edit page
rspec ./spec/requests/user_pages_spec.rb:71 # User pages edit page
rspec ./spec/requests/user_pages_spec.rb:69 # User pages edit page

【问题讨论】:

  • 我认为问题出在utilities.rb 中的sign_in 函数上,并且可能与访问edit_user_path(user) 有关。与这些事情中的一个或两个有关的所有规范都失败了。
  • 我还应该注意我使用的是 simple_form。这会破坏登录功能吗?
  • 由于您修改了原始教程中的代码而没有将其发布在您的问题中,为了帮助某人诊断问题所在,分享您的 sample_app Github 存储库可能符合您的最大利益你最新的(失败的)代码。
  • 好建议 - 这里是:github.com/demosophy/nsent-old

标签: ruby-on-rails factory-bot rspec-rails railstutorial.org


【解决方案1】:

使用describe定义块时,需要将页面访问步骤放入。describe kind 会重置调用后续步骤的上下文。

 describe "with invalid information" do
      before do
      visit edit_user_path(user)
      click_button "Save changes"
      end

      it { should have_content('Whoops') }
 end

在 RSpec 中定义子步骤时,请改用it

【讨论】:

  • 我不认为这是问题,描述块嵌套在首先访问正确路径的块内。无论如何我尝试了代码,它似乎没有改变任何东西(同样的失败)。可能是我误会了?
猜你喜欢
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多