DatabaseCleaner + RSpec : what is the correct configuration? - ruby-on-rails

I included database_cleaner gem in my rails app. Followed the example given on the git repo and included the following code in spec_helper :
Approach 1
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
When i run the rspec i get error as NoMethodError:undefined method 'cleaning' for DatabaseCleaner:Module.
So i did some research and found that i could replace the config.around block above with something like this :
Approach 2
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
OR
Approach 3
config.around(:each) do |example|
DatabaseCleaner.start
example.run
DatabaseCleaner.clean
end
Both Approach 2 and 3 work well.
I also looked in the git repo of database_cleaner and found that cleaning method actually exists and with the following code :
def cleaning(&block)
start
yield
clean
end
which is exactly same as what i did in example 3. If it does exists then why is it not accessible? Am i missing something here. Any more setup?
Or is Approach 2 or 3 preferable?

Finally found the answer,
database_cleaner gem added the cleaning method just last week and also updated the documentation for the same. BUT this change is not available in latest gem version 1.2.0 which I sourced from rubygems.org. Approach 1 works perfectly when i source the gem from github as below:
gem 'database_cleaner', git: 'git#github.com:DatabaseCleaner/database_cleaner.git'

You can use the approach in the documentation if you pull the gem from Github
gem 'database_cleaner', git: 'git#github.com:bmabey/database_cleaner.git'

If you have this same issue using mongoid you can add this to Gemfile, change version to suit you, and run bundle install.
gem 'database_cleaner', '~> 1.4.1'
Then create a support folder in
spec/support/database_cleaner.rb
Require database_cleaner.rb in your spec_helper file, I use gem 'require_all' like so:
# spec/spec_helper.rb
require 'require_all'
require_rel 'support'
Add the following cleaners to database_cleaner.rb
RSpec.configure do |config|
# Cleanup the DB in between test runs
config.before(:suite) do
DatabaseCleaner[:mongoid].strategy = :truncation
DatabaseCleaner[:mongoid].clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Your tests should now tear down properly.

Related

Database_Cleaner with AR-Octopus not cleaning records

We have a project that is using the AR-Octopus gem using sharded databases. The problem we are running into is that the gem 'database_cleaner' is not cleaning records when using this setup, as we are consistently having leftover records in our test database that cause issues with our test suite.
I found this GitHub gist - https://gist.github.com/nowlinuxing/22ea0ab673a5622eb48d
Here is my database_cleaner config file
# spec/support/database_cleaner.rb
require 'database_cleaner'
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
["master", *Octopus.config[Rails.env].keys].each do |shard|
DatabaseCleaner[:active_record, model: ActiveRecord::Base.using(shard)]
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
Has anyone ever encountered this issue? If so, what did you do to resolve the issue? Just looking for some helpful insight.

Clean out, or reset test-database with Rspec and Mongoid 5.0 on Rails 4

When I run my rspec tests, many fail due to stale data in my mongodb database. AFAIK it is far better to test with a clean database.
How can I clean and/or re-seed the database before each test?
You can use database_cleaner gem to accomplish this task.
From their documentation:
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= :truncation
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
As you are using Mongoid ORM, you may also need to specify it explicitly:
# How to setup your ORM explicitly
DatabaseCleaner[:mongoid].strategy = :truncation
Update:
I see an open issue for MongoID 5
To make it work, you can monkey patch the Mongo Ruby driver class as mentioned in the issue.
module Mongo
class Collection
class View
def remove_all
remove(0)
end
end
end
end
Athough it's not a great solution!
The fix to the problem is there in the master branch of database_cleaner(1.4.1) gem. Install the gem from master to fix the problem (until there is the version bump). Expected to get fixed in next version.
gem 'database_cleaner', :git => 'https://github.com/DatabaseCleaner/database_cleaner.git'

Rails 4: Use sqlite memory db for selenium driven tests

I am using a memory sqlite database to run rspec tests. This functions very well. Only when running selenium driven tests (describe "does something", :js => true do) the starting webbrowser gets the error SQLite3::SQLException: no such table: users: SELECT "users".* FROM "users" WHERE ...
WEBrick/1.3.1 (Ruby/2.0.0/2013-02-24) at 127.0.0.1:57827
I am looking for a solution to run selenium driven test while using a in memory database.
Details:
I use ruby on rails 4.0 and the following gems (excerpt)
gem 'sqlite3', '1.3.7'
gem 'rspec-rails', '2.13.0'
gem 'capybara', '~> 2.1.0.beta1'
gem 'selenium-webdriver', '2.35.1'
database.yml
test:
adapter: sqlite3
database: ":memory:"
pool: 5
timeout: 5000
spec_helper.rb
require 'rubygems'
require 'spork'
Spork.prefork do
# snip
load "#{Rails.root.to_s}/db/schema.rb" # set up memory db
RSpec.configure do |config|
config.use_transactional_fixtures = false #using database cleaner
#snip
config.before :suite do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before type: :request do
DatabaseCleaner.strategy = :truncation
end
# Reset so other non-request specs don't have to deal with slow truncation.
config.after type: :request do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before do
DatabaseCleaner.start
ActionMailer::Base.deliveries.clear
end
config.after do
DatabaseCleaner.clean
end
end
end
The problem seems to have something to do that the capybara web server uses its own database connections (as opposed to the connection used by the tests itself), but the in memory database is only available for the one connection which created it.
This question already provided some insights:
(DatabaseError: no such table: django_session) ERROR during Django 1.3 selenium testing
So, how can I make selenium tests memory db compatible?
Thank you very much in advance.
The capybara Readme itself suggests to monkeypatch the ActiveRecord::Basein the spec_helper.rb
class ActiveRecord::Base
mattr_accessor :shared_connection
##shared_connection = nil
def self.connection
##shared_connection || retrieve_connection
end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
If you use spork, the last line belongs to the Spork.each_run section.
In this case, you also have to load the schema.rb in Spork.each_run.
This actually works but is advised to use with caution.
Further information see Why not use shared ActiveRecord connections for Rspec + Selenium?

How to resolve data append in factorygirl while testing?

I am new to rails. i try to write test for a model for that i use factory-girl gem. In that data was taken from XML file.
My problem is when ever am running my rspec file, data was appended every time, in XML file i have only 32 data, but every time am executing rsepc data was increasing...
i even tried database_cleaner but same result.
I want to delete the data in factory-girl.
is there anyway to avoid duplication in factory-girl?
is there anyway to use where condition like query for factory-girl?
Thank you.
Try this:
The following things use to reset factory girl data.
Add following line in your Gemfile and try bundle install.
gem "database_cleaner", ">= 0.8.0", :group => :test
In spec_helper.rb:
RSpec.configure do |config|
# Other things
# Clean up the database
require 'database_cleaner'
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongoid"
end
config.before(:each) do
DatabaseCleaner.clean
end
end

rails test database won't wipe

I'm running rails 3.0.3 and using rspec-rails 2.4.1 with a postgresql database. Whenever I run my RSpec tests, the data remains at the end. Does anyone know how to get rails or rspec to wipe the test environment's data between each use?
Please tell me if there's any further information that could make answering my question easier.
Thanks!Tristan
Install the database_cleaner gem and then add this to your spec_helper.rb.
Spec::Runner.configure do |config|
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Use transactional examples to rollback the data after every test run
RSpec.configure do |config|
config.use_transactional_examples = true
end
You don't need any extra gem in order to clean your test DB between runs. In your spec_helper.rb file, configure rspec as follows:
RSpec.configure do |c|
c.around(:each) do |example|
ActiveRecord::Base.connection.transaction do
example.run
raise ActiveRecord::Rollback
end
end
end
Another possibility, that I just put myself through, is using the wrong before block.
I accidentally set a before block as an all instead of an each:
before :all do
user = FactoryGirl.create(:user)
sign_in user
end
This caused the user to stick around in the database for the entire rspec run, which caused validation collisions.
Instead, the before should be an each so that everything is kept clean through the rspec run:
before :each do
user = FactoryGirl.create(:user)
sign_in user
end
If you've made this mistake, then you will probably need to manually clean up your test database before things go back to normal. The simplest way to do that is probably to truncate each of the tables (aside from schema_migrations).

Resources