Database Cleaner

repository·main·Indexed 25 days ago

https://github.com/databasecleaner/database_cleaner

A collection of Ruby gems providing strategies to clean databases during testing. It supports multiple ORMs and databases via specialized adapters such as database_cleaner-active_record, database_cleaner-sequel, database_cleaner-mongo, database_cleaner-mongoid, and database_cleaner-redis. Key features include various cleaning strategies (truncation, transaction, deletion), lifecycle management via start/clean or cleaning blocks, and integration guides for RSpec, Minitest, and Cucumber, along with production and remote database safeguards.

Tokens
4.1K
Snippets
14
Records
26
Agent score
84%

What's inside Database Cleaner

  1. RSpec with Capybara (Feature Specs) integration

    main

    When using Capybara with drivers that use a separate process (like JavaScript-enabled browsers), the application and the test suite do not share a database connection. In these cases, the :transaction strategy will fail because the app cannot see uncommitted data. You must use the :truncation strategy for these feature specs.

    Note: Ensure config.use_transactional_fixtures is set to false in Rails to prevent conflicts.

    require 'capybara/rspec'
    
    RSpec.configure do |config|
      config.use_transactional_fixtures = false
    
      config.before(:suite) do
        DatabaseCleaner.clean_with(:truncation)
      end
    
      config.before(:each) do
        DatabaseCleaner.strategy = :transaction
      end
    
      config.before(:each, type: :feature) do
        # Use truncation if the driver doesn't share the DB connection
        driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
        unless driver_shares_db_connection_with_specs
          DatabaseCleaner.strategy = :truncation
        end
      end
    
      config.before(:each) do
        DatabaseCleaner.start
      end
    
      config.append_after(:each) do
        DatabaseCleaner.clean
      end
    end
  2. Disable production safeguards

    main

    DatabaseCleaner includes safeguards to prevent accidental database cleaning in production environments by checking ENV, APP_ENV, RACK_ENV, and RAILS_ENV. To bypass this check, you can use an environment variable or a Ruby configuration setting.

    export DATABASE_CLEANER_ALLOW_PRODUCTION=true
    DatabaseCleaner.allow_production = true
  3. Cucumber integration guide

    main

    To manually integrate DatabaseCleaner with Cucumber, create a support file (e.g., features/support/database_cleaner.rb) and use an Around hook to wrap scenarios in a DatabaseCleaner.cleaning block.

    require 'database_cleaner/active_record'
    
    DatabaseCleaner.strategy = :truncation
    
    Around do |scenario, block|
      DatabaseCleaner.cleaning(&block)
    end
  4. Disable remote database safeguards

    main

    DatabaseCleaner prevents running against remote databases by checking if DATABASE_URL excludes localhost, .local, or 127.0.0.1. To allow cleaning a remote database, use an environment variable or a Ruby configuration setting.

    export DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true
    DatabaseCleaner.allow_remote_database_url = true
  5. Minitest integration guide

    main

    For Minitest, you can manually call .start and .clean in before and after hooks, or use the minitest-around gem to use the .cleaning block pattern.

    # Manual approach
    DatabaseCleaner.strategy = :transaction
    
    class Minitest::Spec
      before :each do
        DatabaseCleaner.start
      end
    
      after :each do
        DatabaseCleaner.clean
      end
    end
    
    # Using minitest-around gem
    class Minitest::Spec
      around do |tests|
        DatabaseCleaner.cleaning(&tests)
      end
    end
  6. Install Database Cleaner adapters

    main

    Instead of using the main database_cleaner gem, install the specific adapter for your ORM. Most projects using ActiveRecord will only need database_cleaner-active_record.

    To use multiple ORMs, include multiple gems in your Gemfile within the :test group.

    # Gemfile
    group :test do
      gem 'database_cleaner-active_record'
    end
    
    # For multiple ORMs
    group :test do
      gem 'database_cleaner-active_record'
      gem 'database_cleaner-redis'
    end
  7. RSpec integration guide

    main

    To integrate DatabaseCleaner with RSpec, configure it in your RSpec.configure block. A common pattern is to use :truncation once at the start of the suite and :transaction for individual tests.

    RSpec.configure do |config| 
      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
  8. Configure a DATABASE_URL allowlist

    main

    Instead of allowing all remote databases, you can specify a url_allowlist to restrict DatabaseCleaner to specific connection strings. Elements in the allowlist are matched using case equality (===), meaning you can provide strings, regular expressions, or procs.

    # Using strings
    DatabaseCleaner.url_allowlist = ['postgres://postgres@localhost', 'postgres://foo@bar']
    
    # Using regular expressions
    DatabaseCleaner.url_allowlist = [
      %r{^postgres://postgres@localhost}
    ]
    
    # Using procs for custom logic
    DatabaseCleaner.url_allowlist = [
      proc {|uri| URI.parse(uri).user == "test" }
    ]
  9. Manage database state with start/clean or cleaning blocks

    main

    Some strategies (like :transaction) require a lifecycle management approach. You must either call .start before the test and .clean after, or wrap the test execution in a .cleaning block.

    • Manual approach: Call DatabaseCleaner.start in your test setup and DatabaseCleaner.clean in your teardown.
    • Block approach: Use DatabaseCleaner.cleaning { ... } to automatically handle the lifecycle.
  10. Configure DatabaseCleaner for multiple ORMs or databases

    main

    If your application uses multiple ORMs or multiple database connections, you can specify which one to configure using the DatabaseCleaner[:orm] syntax. You can also specify a specific database connection via the db: option or by passing a model directly.

    require 'database_cleaner/active_record'
    require 'database_cleaner/mongo_mapper'
    
    # Specify particular ORMs
    DatabaseCleaner[:active_record].strategy = :transaction
    DatabaseCleaner[:mongo_mapper].strategy = :truncation
    
    # Specify particular databases via symbol
    DatabaseCleaner[:active_record, db: :two]
    
    # Specify particular databases via a Model
    DatabaseCleaner[:active_record, db: ModelWithDifferentConnection]
  11. Configure and use DatabaseCleaner strategies

    main

    You can set a global strategy or perform one-off cleanings. Common strategies include :truncation, :transaction, and :deletion. A :null strategy (or setting strategy to nil) performs no cleaning.

    To use a strategy with options (like only or except for specific tables), pass them as an array with the strategy name.

  12. Configure the postgres adapter

    main

    When using the postgresql adapter, provide a configuration block with the following keys:

    • adapter: Set to postgresql.
    • database: The name of the database.
    • username: The database user.
    • password: The database password.
    • host: The database host address.
    • encoding: The character encoding (e.g., unicode).
    • template: The database template to use.
    postgres:
      adapter: postgresql
      database: database_cleaner_test
      username: postgres
      password: 
      host: 127.0.0.1
      encoding: unicode
      template: template0