EzDevInfo.com

database_cleaner

Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing. database_cleaner | RubyGems.org | your community gem host

Upgrading capybara from 1.0.1 to 1.1.4 makes database_cleaner break my specs

I have an old Rails application upgraded to version 3.2.11 that has a lot of request specifications written using capybara version 1.0.1 and running using the selenium driver. The database are cleaned after each test using database_cleaner using the truncation strategy.

I want to use poltergeist instead of selenium and upgraded capybara from 1.0.1 to 1.1.4 to be able to use the latest version of poltergeist. Only changing the capybara gem (and its dependencies) introduced problems running my specs.

I consistently get deadlock errors from my Postgresql database in the cleanup handler after each spec. My spec_helper is pretty basic and looks like this:

RSpec.configure do |config|
  config.mock_with :rspec

  config.use_transactional_fixtures = false

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

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

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

The error I get is like this:

An error occurred in an after hook
  ActiveRecord::StatementInvalid: PG::Error: ERROR:  deadlock detected
DETAIL:  Process 41747 waits for AccessExclusiveLock on relation 17612 of database 16396; blocked by process 41752.
Process 41752 waits for RowExclusiveLock on relation 17529 of database 16396; blocked by process 41747.
HINT:  See server log for query details.
: ALTER TABLE "aaa" ENABLE TRIGGER ALL;ALTER TABLE "bbbb" ENABLE TRIGGER ALL;ALTER TABLE "ccc" ENABLE TRIGGER ALL;
  occurred at /xxx/.bundle/gems/activerecord-3.2.11/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `async_exec'

I use FactoryGirl to create test data but otherwise nothing special IMO.

I haven't been able to figure out what holds the other end of deadlock that is created by database_cleaner. Any ideas to figure that out are most welcome.

Anybody know of any changes between capybara 1.0.1 and 1.1.4 that has changed and may have started to cause these issues?


Source: (StackOverflow)

Rails minitest, database cleaner how to turn use_transactional_fixtures = false

i would like to disable use_transactional_fixtures = false in ministest to catch after_commit callback. What and where should i set-up?


Source: (StackOverflow)

Advertisements

Rails Rspec Capybara and DatabaseCleaner - using truncation only on feature tests

I saw this cool method for only using Database cleaners :truncation for capybara test using :js => true

In spec_helper.rb:

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

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

The problem is that any feature test done with capybara seems to need the cleaning strategy to be :truncation.

All the other specs, however, are fine with :transaction, which is significantly faster.

Is there a way of specifying strategy for only capybara feature tests? SOmething like:

DataCleaner.strategy( :truncation ) if :type => :feature

Source: (StackOverflow)

Configure Turnip and Database_cleaner

I'm using Turnip and Ruby on Rails. I have scenarios with and without using javascript. I want to use the transaction DatabaseCleaner strategy for the non-javascript scenarios and the truncation strategy for scenarios marked by @javascript, @selenium and etc.

I'm using following solution for Rspec Features

config.around(:each, :js => true) do |ex|
  DatabaseCleaner.strategy = :truncation
  ex.run
  DatabaseCleaner.strategy = :transaction
end

But it doesn't work in Turnip case. What is the best way to make it works as I expected? Or in other words how to specify turnip scenario marked by @javascript (or @selenium and etc) tag in config.before?


Source: (StackOverflow)

Using rspec, zeus and database_cleaner with two different active_record databases ends in undefined method `query_options' for nil:NilClass error

I'd like to use zeus (0.13.3) to preload my rails environment for an rails (3.2.11) app on ruby 2.0.0 and use database_cleaner (0.9.1) to clean the databases. This is working fine if as long as I use only one mysql database. In the app we have to use two different mysql databases. Edit: What needs to be mentioned is, that I use the shared connection hack, which is described here.

Running my specs without using zeus is working like expected. But if I use it, every test is failing in the moment when a record is created with the error:

undefined method `query_options' for nil:NilClass

How can this be solved?

The setup is like that:

config/database.yml

test:
  database: app_test
  ...

test_second_db:
  database: other_test
  ...

In an abstract base class for all the models using the second connection we do

models/second_db/base.rb

module SecondDB

  class Base < ActiveRecord::Base

    establish_connection "#{Rails.env}_second_db"
    self.abstract_class = true

  end

end

In my spec_helper.rb file I setup the database_cleaner:

spec/spec_helper.rb

require 'database_cleaner'

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

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner[:active_record,{:connection => :test_second_db}].strategy = :transaction
  end

  config.before(:each) do
    DatabaseCleaner.start
    DatabaseCleaner[:active_record,{:connection => :test_second_db}].start
  end

  config.after(:each) do
    DatabaseCleaner.clean
    DatabaseCleaner[:active_record,{:connection => :test_second_db}].clean
  end

end

edit:

spec/support/shared_connection.rb

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end

spec/support/shared_connection.rb


Source: (StackOverflow)

Rails 4 Database cleaner

I'm trying to complete some tests for a rails 4 app and I keep encountering an issue with database_cleaner. The issue is the database is not being cleaned and warnings keep raising:

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

The configuration I have setup in the spec helper is:

require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However,
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.

  # This file is copied to spec/ when you run 'rails generate rspec:install'
  ENV["RAILS_ENV"] ||= 'test'
  require File.expand_path("../../config/environment", __FILE__)
  # require 'rspec/rails'
  require 'rspec/autorun'
  require 'capybara/rspec'
  require 'database_cleaner'

  # Requires supporting ruby files with custom matchers and macros, etc,
  # in spec/support/ and its subdirectories.
  Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

  RSpec.configure do |config|
  # ## Mock Framework
  #
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
  #
  # config.mock_with :mocha
  # config.mock_with :flexmock
  # config.mock_with :rr
  config.mock_with :rspec

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  # config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.filter_run focus: true
  config.run_all_when_everything_filtered = true

  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  # config.use_transactional_fixtures = false

  config.before :each do
    if Capybara.current_driver == :rack_test
      DatabaseCleaner.strategy = :transaction
    else
      DatabaseCleaner.strategy = :truncation
    end
    DatabaseCleaner.start
  end

  config.after do
    DatabaseCleaner.clean
  end


  # If true, the base class of anonymous controllers will be inferred
  # automatically. This will be the default behavior in future versions of
  # rspec-rails.
  # config.infer_base_class_for_anonymous_controllers = false

  # Run specs in random order to surface order dependencies. If you find an
  # order dependency and want to debug it, you can fix the order by providing
  # the seed, which is printed after each run.
  #     --seed 1234
  config.order = "random"
  end
end

And finally here is my gemfile

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0.beta1'

gem 'pg'
gem 'haml-rails', '~> 0.4'
gem 'twitter-bootstrap-rails', '~> 2.2.0'
gem 'annotate', '~> 2.5.0'
group :test do
  gem 'rspec', '~> 2.13.0'
  gem 'rspec-rails', '~> 2.13.0'
  gem 'guard-rspec', '~> 1.2.1'
  gem 'guard-spork', '~> 1.4.2'
  gem 'capybara', '~> 2.0.2'
  gem 'spork', '~> 0.9.2'
  gem 'factory_girl_rails', '~> 4.1.0'
  gem 'shoulda-matchers', '~> 1.4.2'
  gem 'database_cleaner', '~> 0.9.1'
  gem 'launchy', '~> 2.2.0'
  gem 'rb-fsevent', '~> 0.9.2'
  gem 'growl', '~> 1.0.3'
end

group :development do
  gem 'better_errors' ,'~> 0.6.0'
  gem 'binding_of_caller', '~> 0.7.1'
end

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~> 4.0.0.beta1'
  gem 'coffee-rails', '~> 4.0.0.beta1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', platforms: :ruby

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.0.1'

Any help on this issue would be really helpful. Thank you!


Source: (StackOverflow)

When using cucumber and databasecleaner can I keep a single entry in a table?

I am currently using cucumber and databasecleaner to test my application. And currently in my env.rb i have the setup of the cleaner as:

DatabaseCleaner.strategy = :truncation, {:except => %w[TABLE]}
After do
  DatabaseCleaner.clean
end

This way I can keep the data in TABLE. But I would also like to keep a single entry in a different table between tests. Is there any way I can achieve that or do I have to recreate it all the time with a Before hook?


Source: (StackOverflow)

What is the default value of use_transactional_fixtures in rspec?

I am asking this because in the articles I have read so far, concerning rspec and the database_cleaner gem I see the line config.use_transactional_fixtures = false. If I use the database_cleaner gem couldn't I just delete this line?


Source: (StackOverflow)

How do you ensure data created by ActiveRecord Fixtures is rolled back when database_cleaner controls the transaction?

I use ActiveRecord Fixtures to define preset data for tests.

I use the database_cleaner gem to reset the database between tests. I follow the approach described by Avdi Grimm to use truncation for javascript tests, but transactions for non-javascript tests.

Most advice regarding database_cleaner tells you to set config.use_transactional_fixtures = false, without discussing the implications. The implication is that when AR creates the Fixture data, it does not start a transaction. The idea is that database_cleaner will handle starting the transaction, if you use the :transaction strategy.

The problem is that ActiveRecord creates the Fixture data before you get a chance to call DatabaseCleaner.start. That means the fixture data is not part of the transaction, so when database_cleaner rolls back the transaction, the fixture data remains, polluting follow up tests that may not expect that fixture data.

How do I get ActiveRecord to create the Fixture data within the context of the database_cleaner transaction?

I'm using Rails 4.1.0rc1, rspec-rails 2.14.2, rspec 2.14.1, database_cleaner 1.2.0.


Source: (StackOverflow)

DB Cleaner not cleaning database after each test after switching from sqlite to PostgreSQL

This config worked fine when I was using sqlite:

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end
  config.before(:each) do
    controller.stub(:should_navigate_user?).and_return(false) rescue ""
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end

When I switched to PostgreSQL I began getting errors when tests depended on the id number of entries in the database. I looked at the database during the tests and it was never cleaning the database.

If I switch to the following config:

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end
  config.before(:each) do
    DatabaseCleaner.clean
    controller.stub(:should_navigate_user?).and_return(false) rescue ""
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end

All of my tests pass, but I'm having to call clean before and after my methods tests?

I shouldn't have to clean the database before and after each test - right? I feel like I'm misunderstanding something somewhere. What am I failing to understand.


Source: (StackOverflow)

How to truncation all data in a schema different from the Public (database_cleaner)

In my project I use database multi-tenancy 'apartment' gem.

config/initializers/apartment.rb 

Apartment.configure do |config|
 config.excluded_models = %w{ User Company }
end

To clean up the database it tests I use 'database_cleaner' gem

spec/rails_helper.rb

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
    Apartment::Tenant.switch!('app')
  end

  config.after(:each) do
    Apartment::Tenant.switch!
    DatabaseCleaner.clean
  end

end

In RSpec tests with Capybara truncation strategy clean after each test only public schema where only the user and company.

Before test start 
Company.count#=> 0

Other schemes are not cleared.

Before test start
SomeModelInCompanySchema.count#=> 240

How to clear data in another scheme


Source: (StackOverflow)

Rspec extremely slow

My rspec tests seem to run extremely slow even with guard & spork.

Finished in 5.36 seconds
13 examples, 2 failures

I understand that there are several things I can do to optimize my tests & reduce interaction with the database, but I strongly suspect that the spec_helper has been improperly setup. I'm on rails 3.2.11 with mongoid. Database cleaner cleans up after every run.

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

UPDATE: The problem was with one of my tests. It was taking 3 seconds. Please check @Sam Peacey's answer for the command I used to get the below result

Dynamic Model should destroy collection when related source is destroyed
    2.46 seconds ./spec/models/dynamic_model_spec.rb:10
Dynamic Model Validations should validate uniqueness
    0.66357 seconds ./spec/models/dynamic_model_spec.rb:69

Source: (StackOverflow)

typeahead.js test failing on Rails 4 with Cucumber and Capybara-Webkit

I have the following Cucumber feature testing an input form using typeahead.js:

@javascript
Scenario: Creating a battery using typeahead
  When I create a new battery using typeahead
  Then I should be on the show battery page
  And I should see the battery created message

The test fails on the second step with the following error message:

ActiveRecord::RecordNotFound (ActiveRecord::RecordNotFound)
./features/step_definitions/admin/car_part_steps/battery_steps.rb:37:in `/^I should be on the show battery page$/'
features/admin/creating_car_parts/creating_batteries.feature:20:in `Then I should be on the show battery page'

The relevant step definitions are as follows:

When /^I create a new battery using typeahead$/ do
  select_from_typeahead :field => 'battery_manufacturer_typeahead',
    :select => @manufacturer.name
  fill_in 'Type', :with => '700W'
  click_button 'Create Battery'
end

Then /^I should be on the show battery page$/ do
  battery = Battery.find_by_type_and_manufacturer_id!('700W', @manufacturer.id)
  current_path.should == admin_battery_path(battery)
  page.should have_content(battery.type)
end

The select_from_typeahead function is as follows:

def select_from_typeahead(params)
  params[:js_field] ||= params[:field]
  params[:select_typeahead] ||= params[:select]
  fill_in params[:field], :with => params[:select][0, 2]
  page.execute_script "$('##{params[:js_field]}').trigger('focus')"
  page.execute_script "$('##{params[:js_field]}').trigger('keydown')"
  sleep 0.5
  page.execute_script "$('.tt-suggestion:contains(\"#{params[:select_typeahead]}\")').trigger('mouseenter').trigger('click')"
end

The problem appears not to have anything to do with the typeahead itself however, as the code works in the browser, and if I add some debug output, I notice that the battery gets saved to the database in the first step when running the test as well, it just mysteriously disappears before the second step runs.

I think it's an issue with database_cleaner, as I know that doesn't play nice with Javascript when set to use transactions, but I've already tried setting it to use truncation instead and disabled transactional fixtures and it still doesn't work.

My features/support/env.rb currently looks like this:

require 'simplecov'
SimpleCov.start 'rails'

require 'cucumber/rails'

Capybara.default_selector = :css
Capybara.javascript_driver = :webkit

ActionController::Base.allow_rescue = false

Cucumber::Rails::World.use_transactional_fixtures = false
DatabaseCleaner.strategy = :truncation

Cucumber::Rails::Database.javascript_strategy = :truncation

My environment is as follows:

rails 4.0.2
cucumber 1.3.10
cucumber-rails 1.4.0
capybara 2.2.0
capybara-webkit 1.1.0
database_cleaner 1.2.0

Am I missing something, is there some other way database_cleaner might still interfere with my test, or is it something else entirely that I haven't thought of?

Any ideas would be very welcome!


Source: (StackOverflow)

database cleaning for postgres schemas

I have gem devise and gem apartment which I'm using to create separate schemas for each devise's user account.

Apartment's doc and advice in that issue suggest to use Rack middleware to switch between tenants. In that case it's not possible (as far as I know) as I have it user depended rather than request depended.

All works just great except my RSpec tests. The problem is that after every test database is not clean properly (it doesn't remove schema for new created user). All tests pass if I run a small set of them but if I run to many than Faker::Internet.first_name generates usernames that already was taken (which is not valid).

So this is how I did it:

app/controllers/application_controller.rb

def scope_tenant
  Apartment::Database.switch(current_user.username)
end

app/controllers/albums_controller.rb (album model belong_to :user)

class AlbumsController < ApplicationController
  before_action :authenticate_user! # devise magic
  before_action :scope_tenant

app/model/user.rb

after_create :create_schema

private

  def create_schema    
    Apartment::Database.create(self.username)
  end  

This is what I've added to my specs:

spec/factories/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

spec/support/auth_helpers.rb

Warden.test_mode!

def login_and_switch_schema(user)
 login_as(user)
 Apartment::Database.switch(user.username)    # for some reason `login_as()` didn't do that by itself
end

spec/features/albums_spec.rb

feature "Album Pages" do

  given(:user) { create(:user) }
  given(:album) { create(:album) }

  around :each do
    login_and_switch_schema user
  end

  scenario...

As I have some tests with js: true than I have that:

spec/support/database_cleaner.rb

RSpec.configure do |config|

  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

end

Current commit for all sources are available at my github here.

So.. the main question is: how to clean database created schemas for each user after test ? I'll appreciate any other comment as well. Thank you in advance for help.


Source: (StackOverflow)

Using DataBase Cleaner gem with DataMapper

I am writing a test using RSpec and FactoryGirl. In my models DataMappers have been used. Here in RSpec I am testing two methods update and index function of my controller where I am using two objects A, B and C. I have created them by using FactoryGirl as follows:

before(:each) do
  @A = FactoryGirl.create(:A)
  @B = FactoryGirl.create(:B)
  @C = FactoryGirl.create(:C)
end

Now I want to clean them after each test with DataBase Cleaner Gem. I have searched it in Google but most of the articles talk about how to use DataBase cleaner Gem with ActiveRecord but none of them clearly specify how to use DataBaseCleaner gem with DataMapper. So if anyone gives me small example of RSpec file with DataBase cleaner where DataMapper have been used, I will be really grateful. Thanks in advance.


Source: (StackOverflow)