Und*_*ion 5 selenium activerecord rspec ruby-on-rails capybara
根据Capybara 文档,有两种不同的策略来处理Selenium无法访问测试中生成的数据的问题:
猴子补丁ActiveRecord:
class ActiveRecord :: Base @@ shared_connection = nil def self.connection @@ shared_connection || retrieve_connection end end ActiveRecord :: Base.shared_connection = ActiveRecord :: Base.connection
使用截断而不是事务
我已经设置了DatabaseCleaner由Avdi格林概述这里,虽然在看我的日志,我可以清楚地看到DatabaseCleaner使用截短,例如:
(7.4ms)TRUNCATE TABLE"画廊","照片","用户"RESTART IDENTITY CASCADE;
...当我运行我的功能时,我作为设置的一部分创建的任何模型都不可用于驱动程序.我可以看到场景中存在模型,但是如果我将它们打印到页面中,它们就不存在了.
我可以让驱动程序查看模型的唯一方法是使用上面的ActiveRecord monkey-patch,但这似乎会引发许多奇怪的次要问题 - 测试挂起等等.
为什么是它的驱动程序(硒或水豚-的Webkit)无法看到在测试中创建的模型,甚至当我使用DatabaseCleaner使用截断策略,我怎样才能得到水豚用JavaScript的司机工作?
注意:使用默认驱动程序,测试正常
我的DatabaseCleaner配置:
RSpec.configure do |config|
# Clean DB completely
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
# Set default strategy (non-js/Rack::Test)
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
# Set strategy for tests using JS (slower)
config.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
# Wrap DatabaseCleaner around each test (before & after)
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Run Code Online (Sandbox Code Playgroud)
以下是我想使用JavaScript测试的功能示例:
feature "User deletes a photo" do
before {
as_signed_in_user
@gallery = create(:gallery_with_photos)
}
scenario "successfully deletes a photo from a gallery", js: true do
photo_title = @gallery.photos.first.title
puts "GALLERY #{Gallery.find(1)}" # <Gallery:0x007f9b928fe8e8>
visit gallery_path(@gallery) # JavaScript driver can't find gallery
within '.photos-list' do
click_link photo_title
end
click_link('Delete Photo')
expect(current_path).to eq( gallery_path(@gallery) )
expect(page).not_to have_link(photo_title)
end
end
Run Code Online (Sandbox Code Playgroud)
使用JavaScript驱动程序时,此测试失败,并显示:
1) User deletes a photo successfully deletes a photo from a gallery
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::RecordNotFound:
Couldn't find Gallery with 'id'=1
Run Code Online (Sandbox Code Playgroud)
正如Dave Schweisguth在评论中所建议的那样,我试图将其js:true移出到特征而不是场景,而不会产生任何影响.
确保您使用的是最新版本的database-cleaner、capybara、selenium-webdriver。还要确保所有这些宝石都在测试组中并且是require: false
然后在您的spec_helper.rb 文件中,您可以通过在这些gem 之前要求rails 来控制加载顺序。RAILS_ENV确保和的设置正确use_transactional_fixtures
规范助手.rb
require 'rubygems'
ENV['RAILS_ENV'] ||= 'test'
# Load rails + environment
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
# Load database cleaner
require 'database_cleaner'
# Load capybara and its dependencies
require 'capybara/rspec'
require 'capybara/rails'
require 'selenium-webdriver'
RSpec.configure do |config|
# Do not use transactional, let database_cleaner do the work
config.use_transactional_fixtures = false
# Database cleaner config
config.before(:suite) { DatabaseCleaner.clean_with :truncation }
config.before(:each) { DatabaseCleaner.strategy = :transaction }
config.before(:each, js: true) { DatabaseCleaner.strategy = :truncation }
config.before(:each) { DatabaseCleaner.start }
config.after(:each) { DatabaseCleaner.clean }
end
Run Code Online (Sandbox Code Playgroud)
功能规格
尝试使用describe ... type: :feature替代方法,然后移至js: true顶部,如下所示:
describe "User deletes a photo", type: :feature, js: :true do
before { ... }
scenario "successfully deletes a photo from a gallery" do
...
end
end
Run Code Online (Sandbox Code Playgroud)
你的代码
puts "GALLERY #{Gallery.find(1)}"1-即使是为了快速调试也不要编写。在某些情况下,它可能会引发错误并导致混乱(即让您认为问题确实没有解决)。用这个代替puts "GALLERY #{Gallery.find(@gallery.id)}"
2-在 rspec 中使用实例变量也不是一个好的做法,所以不要这样:
before {
as_signed_in_user
@gallery = create(:gallery_with_photos)
}
Run Code Online (Sandbox Code Playgroud)
你应该写这个
before { as_signed_in_user }
let!(:gallery) { create(:gallery_with_photos) }
Run Code Online (Sandbox Code Playgroud)
请注意,我使用let!的是 bang,它相当于before. 因此,在规范的其余部分中,您必须替换@gallery为gallery