0

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

不过,我已经检查了该站点,并且故障并没有出现在现实生活中——所以我认为这是测试套件试图模拟用户的方式的问题——这是有道理的,因为这就是我所做的改变。

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

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

规范/支持/实用程序.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

规格/支持/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
4

1 回答 1

1

When you define a block using describe, you need to put the page visit step in. describe kind of resets the context in which the subsequent steps are called.

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

      it { should have_content('Whoops') }
 end

When you are defining sub step in RSpec, use it, instead.

于 2013-03-29T01:26:19.053 回答