标签: database-cleaner

使用RSPEC进行测试时突然出现无法解释的活动记录连接超时

这是我几乎一无所知的地方,所以请提前道歉.我有一套超过800个rspec测试.在运行整个集合或仅仅是特定的测试文件时突然而且莫名其妙地,在仅仅其中一些之后(例如20个左右,虽然它们的数字从不完全相同),每个单独的测试都会以相同的错误开始失败:

 Failure/Error: Unable to find matching line from backtrace
 ActiveRecord::ConnectionTimeoutError:
   could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)
Run Code Online (Sandbox Code Playgroud)

在典型的运行中,我会在20次左右的请求测试后开始收到这些错误,其余的780+测试都会因上述完全相同的错误而失败.我已经尝试回到之前测试完美的git提交和分支.没有运气 - 仍有780多个失败.还完全删除了重新创建的测试数据库.也没有运气.

我已经阅读了许多关于连接池等的线程,但我恐怕我不知道如何诊断甚至正在发生的事情.以下是我现在所知道的事实:

  • 使用Postgresql
  • 据我所知,开发环境运行良好
  • 在一切工作正常的时候和现在,我没有对我所知道的环境进行任何更改/升级.甚至没有任何数据库迁移.仅仅更改模型,视图和控制器代码.正如我所提到的,回到之前的提交并没有解决任何问题.
  • config.use_transactional_fixtures = false 在spec_helper.rb中,因为我正在通过Selenium测试ajax功能.
  • 但是,无论Selenium是否用于特定的测试集,测试都会失败.即使我只运行不使用Selenium的测试,在20次左右的测试后仍然会出现故障.

我使用Database Cleaner而不是事务夹具,具有以下配置:

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

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  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
Run Code Online (Sandbox Code Playgroud)

有什么想法在这里发生了什么?更具体地说,我应该在哪些想法看看问题是什么?我几乎没有处理此类ActiveRecord问题的经验,我甚至不知道从哪里开始.

更新虽然我仍然不知道为什么会发生这种情况,但我确实知道导致它的代码是什么.在最近的提交中,我添加了在新线程中发送通知电子邮件.这是代码:

    def teacher_notification_email
      Thread.new do
        UserMailer.accepted_parent_invitation_email(@parent_profile).deliver
        ActiveRecord::Base.connection.close
      end
    end
Run Code Online (Sandbox Code Playgroud)

我在应用程序的许多其他地方使用了这个确切的模式(使用不同的电子邮件),所有这些都经过测试.出于某种原因,这个特定的原因导致数据库超时错误.关于为什么会发生这种情况的任何想法都是受欢

更新 由于我还没有理解在这个实例中线程如何工作的阶段,我不知道问题的确切来源,除此之外:从我读过的内容来看,很难以编程方式控制执行以这种方式创建的线程.但是,我找到了解决方案.我已经将块更改为以下块而不是上面的块:

    def teacher_notification_email
      if …
Run Code Online (Sandbox Code Playgroud)

selenium activerecord rspec ruby-on-rails database-cleaner

4
推荐指数
1
解决办法
1428
查看次数

Rspec极其缓慢

我的rspec测试似乎运行速度非常慢,即使有防护和spork.

Finished in 5.36 seconds
13 examples, 2 failures
Run Code Online (Sandbox Code Playgroud)

我知道我可以做几件事来优化我的测试并减少与数据库的交互,但我强烈怀疑spec_helper设置不正确.我在轨道3.2.11与mongoid.每次运行后数据库清理程序都会清理.

spec_helper.rb

require 'rubygems'
require 'spork'
Spork.prefork do
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  require 'rspec/rails'
  require 'rspec/autorun'
  require 'capybara/rspec'

  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  DatabaseCleaner[:mongoid].strategy = :truncation

  RSpec.configure do |config|
    config.infer_base_class_for_anonymous_controllers = false
    config.order = "random"
    config.filter_run focus: true
    config.filter_run_excluding :remove => true
    config.run_all_when_everything_filtered = true
    config.include Mongoid::Matchers
    config.include Capybara::DSL
    ActiveSupport::Dependencies.clear
  end
end


Spork.each_run do
  Fabrication.clear_definitions
  RSpec.configure do |config|
    config.before(:each) do
      DatabaseCleaner.clean
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

更新:问题出在我的一个测试中.这需要3秒钟.请查看@Sam Peacey的答案,了解我用于获得以下结果的命令

Dynamic Model should …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails spork rspec-rails ruby-on-rails-3 database-cleaner

3
推荐指数
1
解决办法
4717
查看次数

Rails 4数据库清理程序

我正在尝试为rails 4应用程序完成一些测试,并且我一直遇到database_cleaner的问题.问题是数据库没有被清理,警告不断提高:

DEPRECATION WARNING: #increment_open_transactions is deprecated and has no effect. (called from block (3 levels) in <top (required)> at /Users/davidhahn/Dev/cta-projects/user-management2/spec/spec_helper.rb:49)
.DEPRECATION WARNING: #increment_open_transactions is deprecated and has no effect. (called from block (3 levels) in <top (required)> at /Users/davidhahn/Dev/cta-projects/user-management2/spec/spec_helper.rb:49)
WARNING:  there is already a transaction in progress
WARNING:  there is already a transaction in progress
.FFFFDEPRECATION WARNING: #increment_open_transactions is deprecated and has no effect. (called from block (3 levels) in <top (required)> at /Users/davidhahn/Dev/cta-projects/user-management2/spec/spec_helper.rb:49)
.DEPRECATION WARNING: #increment_open_transactions is deprecated …
Run Code Online (Sandbox Code Playgroud)

rspec-rails ruby-on-rails-4 database-cleaner

3
推荐指数
1
解决办法
3742
查看次数

数据库清理程序:清除vs截断

以下有什么区别?

  • DatabaseCleaner.clean_with(:截断)
  • DatabaseCleaner.clean

我想弄清楚的是使用数据库清理程序清理我的测试中的before(:all)钩子(性能明智)的最佳方法是什么.我之前的(:all)钩子只是创建了大量的工厂并在它们之间创建了一些关联.目前,我只是将它们全部加载到之前(:每个),不必担心之后的清理.

我目前的策略如下:

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

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

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

  config.after(:each) do
    DatabaseCleaner.clean
  end
Run Code Online (Sandbox Code Playgroud)

所以除了我之前的问题,我的追求(:all)应该是什么样的?

rspec ruby-on-rails capybara database-cleaner

3
推荐指数
1
解决办法
1677
查看次数

DatabaseCleaner 不会重置 Rails 测试单元中的自动增量索引

测试/test_helper.rb:

ENV["RAILS_ENV"] ||= "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'database_cleaner'

DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation, pre_count: true, reset_ids: true)

class ActiveSupport::TestCase
  ActiveRecord::Migration.check_pending!


  def setup
    DatabaseCleaner.start
  end


  def teardown
    DatabaseCleaner.clean
    p '-------- DB Cleaned ---------'
  end

end
Run Code Online (Sandbox Code Playgroud)

我的测试单元文件:(test1和2是重复的)

require 'test_helper'

class ItemTest < ActiveSupport::TestCase

  test "test1" do
    i = Item.create!

    p ActiveRecord::Base.connection.execute("SELECT auto_increment FROM information_schema.tables WHERE table_schema = 'tmi_game_test' AND table_name = 'items';").first

    assert_equal 1, Item.count
    assert_equal 1, i.id
  end

  test "test2" do
    i = Item.create!

    p ActiveRecord::Base.connection.execute("SELECT auto_increment FROM information_schema.tables …
Run Code Online (Sandbox Code Playgroud)

unit-testing ruby-on-rails database-cleaner

3
推荐指数
1
解决办法
1745
查看次数

Rails minitest,数据库更清洁如何转为use_transactional_fixtures = false

我想在ministest中禁用use_transactional_fixtures = false来捕获after_commit回调.我应该在什么地方和哪里设置?

ruby-on-rails minitest database-cleaner

2
推荐指数
1
解决办法
2411
查看次数

postgres模式的数据库清理

gem devisegem apartment我正在使用以创建每个色器件的用户帐户是不同的模式.

公寓的文档该问题的建议建议使用Rack中间件在租户之间切换.在那种情况下,我不可能(据我所知),因为我有用户依赖而不是请求依赖.

除了我的RSpec测试之外,所有工作都很棒.问题是每个测试数据库都没有正确清理后(它不会删除新创建的用户的模式).如果我运行一Faker::Internet.first_name小组它们,但是如果我运行多次而不是生成已经采用的用户名(这是无效的),则所有测试都会通过.

所以这就是我做到的:

应用程序/控制器/ application_controller.rb

def scope_tenant
  Apartment::Database.switch(current_user.username)
end
Run Code Online (Sandbox Code Playgroud)

app/controllers/albums_controller.rb(专辑模型belong_to :user)

class AlbumsController < ApplicationController
  before_action :authenticate_user! # devise magic
  before_action :scope_tenant
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ user.rb

after_create :create_schema

private

  def create_schema    
    Apartment::Database.create(self.username)
  end  
Run Code Online (Sandbox Code Playgroud)

这是我添加到我的规格中的内容:

规格/工厂/ user.rb

FactoryGirl.define do
  factory :user do
    username { Faker::Name.first_name }
    email { Faker::Internet.email("#{username}") }
    password "login_as will not use it anyway"
  end
end
Run Code Online (Sandbox Code Playgroud)

规格/支持/ auth_helpers.rb

Warden.test_mode!

def login_and_switch_schema(user)
 login_as(user)
 Apartment::Database.switch(user.username)    # …
Run Code Online (Sandbox Code Playgroud)

postgresql rspec ruby-on-rails devise database-cleaner

1
推荐指数
1
解决办法
1570
查看次数

RSpec,Factory Girl和Capybara:没有保存任何物品

我有RSpec可安装的Rails引擎:

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

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

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

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
Run Code Online (Sandbox Code Playgroud)

简单工厂:

FactoryGirl.define do
  factory :post, :class => MyEngine::Post do
    title 'title'
  end
end
Run Code Online (Sandbox Code Playgroud)

水豚特色:

require 'spec_helper'

describe 'Post', :type => :feature do
  let(:post) { FactoryGirl.create :post }

  it 'index action should have post' do
    visit posts_path
    expect(page).to have_text(post.title)
  end
end
Run Code Online (Sandbox Code Playgroud)

Post模型没有任何验证.

但是当我运行测试时,它表明没有创建帖子.

还有ActiveRecord日志:

INSERT INTO "my_engine_posts" ...
RELEASE SAVEPOINT active_record_1
rollback transaction
Run Code Online (Sandbox Code Playgroud)

rspec ruby-on-rails capybara database-cleaner factory-bot

1
推荐指数
1
解决办法
355
查看次数