RSpec / Capybara不会在测试中承诺DB

时间:2017-02-09 08:52:19

标签: ruby-on-rails rspec capybara

自从将我们的测试套件从Minitest转移到RSpec后,我非常绝望。到目前为止,所有的控制器和模型测试运行正常,但是由于尝试移植(以前通过/工作)功能测试,如下所示我遇到了麻烦......

<html>
  <body>
    <h1>its working </h1>
    first view <br>
    <form action ='' method = 'POST'> {% csrf_token %}
        {{form.as_p}}
        <input type='submit' name='submit'>
    </form>

    2nd view<br>
    <form action='' method='POST'>  {% csrf_token %}
        {{f.as_p}}
        <input type='submit' name='submit'>
    </form>
  </body
</html>

不幸的是,这不会导致数据库提交导致测试失败。如果我DateTimeFormatter formatter= DateTimeFormat.forPattern("hh:mm aa"); 进入测试并手动创建请求的位置,它不会失败。我尝试了不同的方法来触发按钮但到目前为止没有任何工作。

这就是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: 'schnipp@schnapp.com') fill_in('place_homepage', with: 'http://schnapp.com') fill_in('place_phone', with: '03081763253') end end 的样子:

pry

有没有人对可能的原因有所了解?宝石版本:

  • capybara 2.12.0
  • rspec 3.5.0
  • rails 4.2.7.1

最好的,谢谢, 岸堤

--- 更新

我添加了rails_helper.rb方法

这是测试在启用或不启用Capybara JS驱动程序的情况下失败的方式(在此测试的情况下无关紧要,因为该功能不使用任何JS)。不幸的是,它没有提供任何真正的提示......

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: 'user@example.com'
  visit 'login/'
  fill_in 'sessions_email', with: 'user@example.com'
  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

我发现了与capyara无关的问题。实际上我忘了为我们正在调用的API转移存根响应。谢谢大家参与我的斗争!

1 个答案:

答案 0 :(得分:2)

您的测试中存在许多可能导致您所看到的问题的潜在问题,如果您包含测试产生的实际错误消息,将来会更容易缩小范围。

  1. 您的情节/功能未标记为:使用Capybara驱动程序激活的js元数据。您可能已在某处指定Capybara.default_driver,但如果是,那么您的DatabaseCleaner配置错误

  2. 使用https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example中推荐的DatabaseCleaner配置。如果您已在#1中指定Capybara.default_driver并且还使用:js /:驱动程序元数据使用模式,则驱动程序名称检测将起作用。此外,append_after / after差异对于降低测试片状度非常重要

  3. 您的login_as_user方法需要在返回之前验证登录是否已完成。这是因为click_on 'Login'可以异步触发并在登录实际发生之前返回。这导致您在中止登录后立即调用visit,阻止会话cookie被发送,并在您希望用户登录时以非登录用户结束。要解决此问题,您需要一些东西像

    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
    

    click_button('Create Place')visit '/places'之间存在同样的问题,访问可以有效取消按钮点击的效果