2017-02-09 96 views
1

自從將我們的測試套件從Minitest移動到RSpec後,我非常絕望。所有控制器和模型試驗細跑這麼遠,但由於試圖端口(原通/工作)功能測試,如我遇到了麻煩下面...RSpec /水豚在測試中沒有提交到數據庫

feature 'Create place' do 
    scenario 'create valid place as user' do 
    login_as_user 
    visit '/places/new' 
    fill_in_valid_place_information 
    click_button('Create Place') 
    visit '/places' 
    expect(page).to have_content('Any place', count: 1) 
    end 

    ... 

    def fill_in_valid_place_information 
     fill_in('place_name', with: 'Any place') 
     fill_in('place_street', with: 'Magdalenenstr.') 
     fill_in('place_house_number', with: '19') 
     fill_in('place_postal_code', with: '10963') 
     fill_in('place_city', with: 'Berlin') 
     fill_in('place_email', with: '[email protected]') 
     fill_in('place_homepage', with: 'http://schnapp.com') 
     fill_in('place_phone', with: '03081763253') 
    end 
end 

不幸的是這並不會導致DB提交這使得測試失敗。它不會失敗,如果我pry進入測試並手動創建請求的地方。我嘗試了不同的方法來觸發按鈕,但目前爲止沒有任何工作。

這是我rails_helper.rb看起來像:

ENV['RAILS_ENV'] ||= 'test' 
require File.expand_path('../../config/environment', __FILE__) 
abort("The Rails environment is running in production mode!") if Rails.env.production? 
require 'spec_helper' 
require 'rspec/rails' 
require 'capybara/rspec' 
require 'capybara/rails' 
require 'capybara/poltergeist' 
require 'pry' 

def validate_captcha 
    fill_in 'captcha', with: SimpleCaptcha::SimpleCaptchaData.first.value 
end 

def login_as_user 
    user = create :user, email: '[email protected]' 
    visit 'login/' 
    fill_in 'sessions_email', with: '[email protected]' 
    fill_in 'sessions_password', with: 'secret' 
    click_on 'Login' 
end 

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } 

ActiveRecord::Migration.maintain_test_schema! 

Capybara.register_driver :poltergeist do |app| 
    Capybara::Poltergeist::Driver.new(app, phantomjs_options: ['--ignore-ssl-errors=true']) 
end 

Capybara.javascript_driver = :poltergeist 

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

    config.before(:suite) do 
    DatabaseCleaner.clean 
    end 

    config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

    config.before(:each, no_transaction: true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each, js: true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
    DatabaseCleaner.start 
    end 

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

    config.include Capybara::DSL 
    config.include Rails.application.routes.url_helpers 
    config.fixture_path = "#{::Rails.root}/spec/fixtures" 
    config.infer_spec_type_from_file_location! 
    config.filter_rails_from_backtrace! 
end 

有沒有人有一個關於一個可能的原因的線索?寶石版本:

  • 水豚2.12.0
  • rspec的3.5.0
  • 軌4.2.7.1

最好的和感謝, 安迪

--- 更新

我加了fill_in_valid_place_information方法

這是測試如何啓用或未啓用Capybara JS驅動程序失敗(應該無關緊要,因爲該功能不使用任何JS)。遺憾的是它不給任何真正的線索一起工作......

1) Create place create valid place as user 
    Failure/Error: expect(page).to have_content('Any place', count: 1) 

     expected to find text "Any place" 1 time but found 0 times in "KIEZ KARTE Find places Here comes a list of all POIs currently available in our database. If you are looking for a specific location please enter parts of its descriptive features into the 'Search' field. Search: Name Postal code Categories No data available in table" 

     Timeout reached while running a *waiting* Capybara finder...perhaps you wanted to return immediately? Use a non-waiting Capybara finder. More info: http://blog.codeship.com/faster-rails-tests?utm_source=gem_exception 

--- 更新2

我發現這是不capyara相關的問題。其實我忘記了爲我們打電話的API傳輸存根響應。謝謝大家參與我的鬥爭!

+0

您可以發佈fill_in_valid_place_information方法? –

+0

嘿,謝謝。我更新了答案,包括方法和失敗信息(這不是很有幫助) –

回答

2

測試中有很多潛在的問題可能會導致您所看到的情況,如果您將測試產生的實際錯誤信息包含在內,未來將會更容易縮小範圍。

  1. 您的場景/功能沒有標記:js metadata使用Capybara驅動程序激活。您可能在某處指定了Capybara.default_driver,但如果是這樣,那麼您的DatabaseCleaner配置不正確

  2. 使用https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example中推薦的DatabaseCleaner配置。如果您指定了#1中提到的Capybara.default_driver,並且還使用了:js /:driver元數據使用模式,那麼驅動程序名稱檢測將起作用。此外,append_after/after差異對於減少測試性片狀很重要

  3. 您的login_as_user方法需要在返回之前驗證登錄已完成。這是因爲click_on 'Login'可以異步觸發並在登錄實際發生之前返回。這會導致visit在您中止登錄後立即致電,阻止發送會話cookie,並在您希望用戶登錄時以非登錄用戶結束。要解決此問題,您需要類似

    click_button('Create Place')visit '/places'之間存在
    def login_as_user 
        ... 
        click_on 'Login' 
        expect(page).to have_text('You are now logged in!') #whatever message is shown on successful login, or use have_css with some element on the page that only exists when a user is logged in (user menu, etc) 
    end 
    

    同樣的問題,即通過此次訪問能夠有效地取消按鈕的作用點擊

+0

嘿托馬斯,感謝您的全面答覆。 1.測試的功能不包含任何JS。總之,即使使用:js標籤也會失敗。 2.我做了,沒有改變。 3.登錄已完成,我明白了。即使沒有登錄,軟件的邏輯也允許提交,所以這不成問題。另外:測試,因爲它是行之有效的 - 「在概念上」 - Minitest -.- –

+0

@ A.Neumann你的代碼是否依賴於'after_commit'回調? –

+0

它呢,我有兩個'after_create'回調 –