Getting RSpec, Postgres, DatabaseCleaner to play nicely together

Did a quick benchmark last week to find the optimal way to configure Rspec on our projects that use Postgres and DatabaseCleaner

One of our test suites takes 3.5 minutes to run when we do NOT use DatabaseCleaner, the default rspec setup:

# spec_helper.rb
#config.use_transactional_examples = false 
#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

When we enabled database cleaner (with default .strategy = :transaction), the test still took 3.5 minutes, but we got lots of warnings:*WARNING: there is already a transaction in progress
NOTICE: there is no transaction in progress
*

# spec_helper.rb
 #config.use_transactional_examples = false 
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  

However, when we changed the .strategy to :trunctation, it eliminated the warnings, but slowed the tests down to 8 minutes!# spec_helper.rb

#config.use_transactional_examples = 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  

The best results were to leave the strategy set to :transaction, but set config.usetransactionalexamples = false. That yielded a runtime of about 3.5 minutes.

# spec_helper.rb
 config.use_transactional_examples = false 
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  

We used the following addition spec to verify that the database was being cleaned. (run this with –order default )

#dbclean_spec.rb

require "spec_helper"  
Refer.destroy_all  
describe Refer do  
it "has none to begin with" do  
  Refer.count.should == 0 
end  
it "has one after adding one" do  
Refer.create  
Refer.count.should == 1  
end  
it "has none after one was created in a previous example" do Refer.count.should == 0  
end  
end