9

個人の請求用の設定画面を作成しています。コントローラ/ビューはAdmin名前空間にあります。

:js => trueを指定せずに最初のテストを実行すると、1つの失敗が発生します。これは、リンクがjsスクリプトを使用してネストされたフィールドのセットを構築するヘルパーとして機能しないという事実に起因すると思います(Railscastに基づく)単一のフォーム、複数のテーブル-ネストされた属性)。

Failures:

  1) Patient Setup create patient bill heading - with extended details -with valid data
     Failure/Error: fill_in "Extended Bill Heading", :with => 'Regular Registration'
     Capybara::ElementNotFound:
       cannot fill in, no text field, text area or password field with id, name, or label 'Extended Bill Heading' found
     # (eval):2:in `fill_in'
     # ./spec/requests/admin/patient_setup_pages_spec.rb:52:in `block (4 levels) in <top (required)>'

Finished in 0.83047 seconds
3 examples, 1 failure, 2 pending

しかし、:js = trueを使用すると、ログインによるものと思われるエラーが発生し、実行時に無効なユーザー/パスワードが画面に点滅します。

ここに画像の説明を入力してください

Failures:

  1) Patient Setup create patient bill heading - with extended details -with valid data
     Failure/Error: click_link 'System'
     Capybara::ElementNotFound:
       no link with title, id or text 'System' found
     # (eval):2:in `click_link'
     # ./spec/requests/admin/patient_setup_pages_spec.rb:22:in `block (2 levels) in <top (required)>'

Finished in 6.33 seconds
3 examples, 1 failure, 2 pending

これをすべてバックアップするコードは次のとおりです。

spec/requests/admin/patient_setup_spec.rb

require 'spec_helper'

feature 'Patient Setup' do

  let!(:ci_user) { FactoryGirl.create(:user, 
                                       name: "configuration engineer", 
                                       password: "password",
                                       password_confirmation: "password"
                                     ) }
  let!(:admin_role) { FactoryGirl.create(:admin_role) }
  let!(:assignment) { FactoryGirl.create(:assignment, 
                                         :role => admin_role, 
                                         :user => ci_user 
                                         ) } 

  before do 
    visit login_path
    fill_in "Name", with: "configuration engineer"
    fill_in "Password", with: "password"
    click_button "Login"
    save_and_open_page
    click_link 'System'
    click_link 'Patient Setup'
  end

  describe "create patient bill heading" do
    before do
      click_link 'New Bill Heading'
      fill_in 'Bill heading', :with => 'Consultation' 
      fill_in 'Abbreviation', :with => "CON"       
    end

    context "- no extended details" do
      pending

      scenario "- with valid data" do
        pending
        click_button 'Create Patient bill heading' 
        page.should have_content('Patient Bill Heading created.')
      end
    end

    context "- with extended details", :js => true do #(without :js => true 1st error)
      before do
        # save_and_open_page
        click_link "Extended Bill Heading"
        # save_and_open_page        
      end

      scenario "-with valid data" do
        save_and_open_page
        fill_in "Extended Bill Heading", :with => 'Regular Registration'
      end
    end

  end
end

これが私の工場設定です。

spec/factories.rb

FactoryGirl.define do

  # Users, Roles
  factory :user do
    name     "Joesephine Bloggs"
    password "testmenow"
    password_confirmation "testmenow"
  end

  factory :admin, :class => User do
    sequence(:name) { |n| "Administrator-#{n}" }
    password "adminiam"
    password_confirmation "adminiam"
    after(:create) do |user|
      FactoryGirl.create(:assignment, :role => FactoryGirl.create(:admin_role), :user => user )
    end
  end

  factory :role do
    description { "Clerical-#{rand(99)}" }

    factory :admin_role do
      description "Admin"
    end
  end

  factory :assignment do
    user
    role
  end

  # Patients Module

  factory :patient_bill_heading do


      sequence(:bill_heading) { |n| "bill-heading-#{n}" }
      sequence(:abbreviation) { |n| "abbreviation-#{n}" }


      factory :delete_patient_bill_heading, :class => PatientBillHeading do
        bill_heading :bill_heading
        abbreviation :abbreviation
      end

  end  
end

ネストされた属性フィールドを生成するヘルパーを呼び出すための私のビューのリンクは次のとおりです。

<p>
  <%= link_to_add_fields "Extended Bill Heading", f, :patient_extended_bill_headings %>
</p>

そして、ここにヘルパーがあります。

helpers/application_helper.rb

  def link_to_add_fields(name, f, association, options={})
    defaults = {
      :partial_name => nil
    }
    options = defaults.merge(options)

    new_object = f.object.send(association).klass.new
    id = new_object.object_id
    fields = f.fields_for(association, new_object, child_index: id) do |builder|
      if options[:partial_name].nil?
        render(association.to_s.singularize + "_fields", f: builder)
      else
        render(options[:partial_name], f: builder)
      end
    end
    link_to("#{name} <i class='icon-plus icon-white'></i>".html_safe, 
            '#', 
            class: "btn btn-success add_fields",
            data: {id: id, fields: fields.gsub("\n", "")}
           )
  end

テストが失敗する理由を理解しようとして1時間後に、アプリケーションでこれが正常に機能するように構築できたため、RSpecテストの知識を向上させようとしています。したがって、アプリでは機能しますが、テストに合格する方法を理解したいと思います。

jsを使用してリンクを作成したことが原因の1つであり、:js => trueオプションを使用していないため、capybaraがそれを実行していないという私の主張はありますか?

:js => trueオプションを使用しているときに、私が間違っていることを誰かが確認できますか?

4

1 に答える 1

24

あなたはおそらくconfig.use_transactional_fixtures = trueあなたのspec_helper.rbにあります。サーバーとブラウザクライアントは別々のスレッドで実行されるため、Capybarajavascript仕様では機能しません。サーバー上のデータベーストランザクションはクライアントに表示されないため、クライアントはlet!()で作成したユーザーについての手がかりがないため、ユーザーはシステムにログインできません。

トランザクションフィクスチャをオフにして、js仕様の各実行の前後にデータベースをクリーンアップする必要があります(gem database_cleanerを検討してください)。

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.clean_with :truncation
  end

  config.before(:each) do
    if example.metadata[:js]
      DatabaseCleaner.strategy = :truncation
    else
      DatabaseCleaner.strategy = :transaction
    end
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

上記のコードスニペットは、連絡先管理アプリのreadmeから取得され、わずかに変更されています

于 2012-11-05T15:15:50.970 に答える