加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 是否可以在不修补ActiveRecord的情况下使用Sel

发布时间:2020-12-16 21:03:04 所属栏目:百科 来源:网络整理
导读:根据Capybara Docs,有两种不同的策略来处理Selenium无法访问测试中生成的数据的问题: 猴子补丁ActiveRecord: class ActiveRecord :: Base @@ shared_connection = nil def self.connection @@ shared_connection || retrieve_connection 结束 结束 ActiveR
根据Capybara Docs,有两种不同的策略来处理Selenium无法访问测试中生成的数据的问题:

>猴子补丁ActiveRecord:

class ActiveRecord :: Base
@@ shared_connection = nil
def self.connection
@@ shared_connection || retrieve_connection
结束
结束
ActiveRecord :: Base.shared_connection = ActiveRecord :: Base.connection
>使用截断而不是事务

我按照Avdi Grimm here的描述设置了DatabaseCleaner,虽然查看我的日志但我可以清楚地看到DatabaseCleaner正在使用截断,例如:

(7.4ms)TRUNCATE TABLE“画廊”,“照片”,“用户”RESTART IDENTITY CASCADE;

…当我运行我的功能时,我作为设置的一部分创建的任何模型都不可用于驱动程序.我可以看到场景中存在模型,但是如果我将它们打印到页面中,它们就不存在了.

我可以让驱动程序查看模型的唯一方法是使用上面的ActiveRecord monkey-patch,但这似乎会引发许多奇怪的次要问题 – 测试挂起等等.

为什么驱动程序(Selenium或Capybara-Webkit)无法看到在测试中创建的模型,即使我使用DatabaseCleaner进行截断策略也是如何让Capybara使用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

以下是我想使用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

使用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

正如Dave Schweisguth在评论中所建议的那样,我已经尝试将js:true移动到特征而不是没有任何影响的场景.

解决方法

确保您使用的是数据库清理程序,capybara,selenium-webdriver的最新版本
.还要确保所有这些宝石都在测试组中,并且要求:false

然后在spec_helper.rb文件中,您可以通过在这些宝石之前要求rails来控制加载顺序.确保RAILS_ENV和use_transactional_fixtures的正确设置

spec_helper.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

功能规格

尝试使用describe … type :: function,并在顶部移动js:true,如下所示:

describe "User deletes a photo",type: :feature,js: :true do
  before { ... }
  scenario "successfully deletes a photo from a gallery" do
    ...
  end
end

你的代码

1-即使是为了快速调试,也不要写“GALLERY#{Gallery.find(1)}”.它可能会在某些情况下引发错误并导致混淆(即让你认为问题确实没有解决).使用此代替“GALLERY#{Gallery.find(@ gallery.id)}”

2-此外,在rspec中使用实例变量不是一个好习惯,所以不要这样做:

before {
  as_signed_in_user
  @gallery = create(:gallery_with_photos)
}

你应该写这个

before { as_signed_in_user }
let!(:gallery) { create(:gallery_with_photos) }

请注意,我使用let!砰的一声,相当于以前.因此,在您的其他规范中,您必须用gallery替换@gallery

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读