Closed paudelprerana closed 6 years ago
@paudelprerana Could you try with database_cleaner v1.5.3 and report back?
@etagwerker I tested with database_cleaner v1.5.3 and its not working.
@paudelprerana Hi , I was also facing the same issue while trying to clean my database with Database Cleaner. Then i tried to clean database in some other machine having exactly the same configuration for ruby, rails, mongoid, database cleaner version, and yes it was working fine.
The issue on my machine was because of the mongo version. I have installed the latest version of mongo
i.e 3.2.8
and on other machine it was an older version i.e 2.4.12
. Then i installed an old release of mongo, and database cleaner started working fine.
What is your mongo version ? Please install a version below 2.7 and tell me if its working.
I'm having this issue but with Postgres, I am using Postgres 9.5 with Rails 5.
module DatabaseHelper
def self.before_all
self.before_suite
end
def self.before_suite
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
def self.establish_connection
connection_info = Rails.configuration.database_configuration[Rails.env]
ActiveRecord::Base.establish_connection(connection_info)
end
def self.around(example: example = nil, block: block = nil)
if example
DatabaseCleaner.cleaning do
example.run
end
elsif block
DatabaseCleaner.cleaning(&block)
end
end
end
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseHelper.before_suite
end
config.around(:each) do |example|
DatabaseHelper.around(example: example)
end
end
I have the same issues, DataCleaner not cleaning. I am also using Postgres 9.5 and Rails 5.
Here is my database_cleaner.rb file:
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
And in the file rspec_helper.rb I added a line like this: config.include FactoryGirl::Syntax::Methods
and I changed an existent one like this: config.use_transactional_fixtures = false
After each run, my records count in the table is increased: Failures:
1) OrganizationsController POST #create with valid attributes create new organization Failure/Error: expect(Organization.count).to eq(1)
expected: 1
got: 15
To help narrow down these issues, you might try a blank rails 5 app with just two tests and see if you can reproduce the error by changing one thing at a time. I just tried a new rails 5 app with postgres 9.5, and it's working fine for me. Here's a start:
mkdir db-cleaner-test
cd db-cleaner-test
rails new . -T --database=postgresql
echo "gem 'rspec'" >> Gemfile
echo "gem 'database_cleaner'" >> Gemfile
bundle install
rails g rspec:install
echo "--require rails_helper" >> .rspec
rails g migration create_people
echo "class Person < ApplicationRecord; end" > app/models/person.rb
Then setup database.yml
to point to a local postgres server, and run rails db:setup
Add in the default database_cleaner stuff:
spec/rails_helper.rb:
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
Finally, add a spec that will test your person model, something like:
spec/models/person_spec.rb:
describe "Person" do
before { Person.create }
it "should have 1 person the first time" do
expect(Person.count). to be 1
end
it "should still only have 1 person the second time" do
expect(Person.count). to be 1
end
end
Now... figure out how to make it fail and post back here!
P.S. Sorry, I've never used mongoid, so I'm not sure what the corresponding steps would be, but it can't be too difficult to modify :wink:
I got a similar problem with rails 5.0.2, ActiveRecord and a transaction strategy. I switched to truncation, it now works correctly.
I added a new strategy. The transaction isn't clear across all threads
require 'database_cleaner/active_record/base'
require 'database_cleaner/generic/transaction'
module DatabaseCleaner::ActiveRecord
class Transaction4
include ::DatabaseCleaner::ActiveRecord::Base
include ::DatabaseCleaner::Generic::Transaction
def start
@fixture_connections = enlist_fixture_connections
@fixture_connections.each do |connection|
connection.begin_transaction joinable: false
end
end
def clean
@fixture_connections.each do |connection|
connection.rollback_transaction if connection.transaction_open?
end
@fixture_connections.clear
connection_class.clear_active_connections!
end
def enlist_fixture_connections
connection_class.connection_handler.connection_pool_list.map(&:connection)
end
end
end
I tried your new strategy and it works perfectly!
DatabaseCleaner.strategy = DatabaseCleaner::ActiveRecord::Transaction4.new
This probably justifies a PR, don't you think?
probably. https://github.com/rails/rails/blob/5-0-stable/activerecord/lib/active_record/fixtures.rb#L963 if you want some context around what is going on
I've switched back to truncation because event with the fix suggested by @ryanong it fails sometimes to properly reset the database 😢
Is anyone getting the same problem with the transaction strategy?
[SOLVED]
I'm having the same problem, with Rails 5.1.4 and PostgreSQL 9.5.10. Might this be related to environments? Does database_cleaner know it has to clean the test database without any config?
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
end
Edit: This wasn't actually a problem in the gem. I was doing something wrong in RSpec. My code was creating the records in a before(:all) block, while the DatabaseCleaner.clean call was being performed in a before(:each) block. And as I was using the Transaction strategy, the transactions that created the records were not able to be rolled back by the gem and hence no deletion was being done.
After I added the record creation to the before(:each) block, the database cleaning worked OK. Also, it could've been "solved" by using the Truncation strategy, since it doesn't depend on the transactions.
Hope this helps to anyone having the same problem I had.
@mgiagante thank you for your post! Rails: 5.1.4 MySql2: 0.4.10
I had modified spec/support/databse_cleaner.rb
(remembering to include the file in rails_helper.rb
below require 'support/factory_bot'
and to set config.use_transactional_fixtures = false
) in a variety of ways and nothing worked. Each time I ran my tests, the previous database objects persisted.
Solution:
spec/support/databse_cleaner.rb
, delete it. require 'database_cleaner'
to spec/support/rails_helper.rb
, delete it. spec/support/rails_helper.rb
, update your RSpec.config
to the following (basically the same as @mgiagante's plus the rspec defaults):RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# 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(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, :category => :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
end
@LauraKirby's solution worked for me. (OpenBSD 6.1, Rails 5.1.4, PostgreSQL 9.6.2)
@LauraKirby I'm glad to be of help! As far as I know, it doesn't matter if the configuration is split into two files or unified, as long as it is correctly defined. So don't hesitate to extract parts of it to additional files and require them if it adds up to your code organization.
rails 5.1 updated their transaction strategy so I re-ported it over
require 'database_cleaner/active_record/base'
require 'database_cleaner/generic/transaction'
module DatabaseCleaner::ActiveRecord
class Transaction5
include ::DatabaseCleaner::ActiveRecord::Base
include ::DatabaseCleaner::Generic::Transaction
def start
@fixture_connections = enlist_fixture_connections
@fixture_connections.each do |connection|
connection.begin_transaction joinable: false
connection.pool.lock_thread = true
end
# When connections are established in the future, begin a transaction too
@connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
spec_name = payload[:spec_name] if payload.key?(:spec_name)
if spec_name
begin
connection = ActiveRecord::Base.connection_handler.retrieve_connection(spec_name)
rescue ConnectionNotEstablished
connection = nil
end
if connection && !@fixture_connections.include?(connection)
connection.begin_transaction joinable: false
connection.pool.lock_thread = true
@fixture_connections << connection
end
end
end
end
def clean
ActiveSupport::Notifications.unsubscribe(@connection_subscriber) if @connection_subscriber
@fixture_connections.each do |connection|
connection.rollback_transaction if connection.transaction_open?
connection.pool.lock_thread = false
end
@fixture_connections.clear
connection_class.clear_active_connections!
end
def enlist_fixture_connections
connection_class.connection_handler.connection_pool_list.map(&:connection)
end
end
end
I came across this issue today. Eventually, I realised that the records that weren't being cleaned were being created within a before(:all)
block in one of my specs.
Posting here in case anyone else makes the same error.
@Bodacious I also met same problem like you. Below is the solution of your problem. https://github.com/DatabaseCleaner/database_cleaner/issues/489 If you don't mention the problem, I can't solve that! Thank you.
Configuratin in spec_helper.rb is as:-
ruby
RSpec.configure do |config| config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end config.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true endClean up the database, database_cleaner setup with Rspec.
require 'database_cleaner'
config.before(:suite) do DatabaseCleaner.orm = 'mongoid' DatabaseCleaner.strategy = :truncation end
config.before(:each) do DatabaseCleaner.start end
config.after(:each) do DatabaseCleaner.clean end end