DatabasePlumber 
A common problem in test suites for large [Rails][rails] applications is that, as they mature, balancing test speed and complexity often results in heavy use of tools like [FactoryGirl][factorygirl] and [DatabaseCleaner][databasecleaner].
These are powerful and useful tools, but over time it often becomes evident that large factories can create and orphan many rows in the database; combine with the need for non-transactional database maintenance during [Capybara][capybara] tests and its very easy to be plagued by mystery guests.
DatabasePlumber is a quick utility that checks for rows left after an example group has been executed, publishes a report and cleans up.
Why use this?
Well, for starters, it acts as a quick sticking plaster on the problem of mystery guests, giving you back confidence in your CI runs in the short term.
Long-term, it removes the fear from optimizing the persistence of objects using
[RSpec][rspec] before(:all) blocks by making it clear when you, or your factories
have not cleaned up properly after.
Installation
Add this line to your application's Gemfile:
gem 'database_plumber', github: 'brrygrdn/database_plumber'
And then execute:
$ bundle
Usage
To get started, add the following lines to your spec_helper.rb
RSpec.configure do |config|
...
config.after(:each) do |example|
DatabaseCleaner.clean
# Notify DatabasePlumber of each example after it has been executed
DatabasePlumber.log example
end
config.after(:all) do
# Perform the report after each example group
DatabasePlumber.inspect
end
...
end
Run your tests as normal, and you'll see a report after any examples:
> bundle exec rspec spec/models/
.....
#### Leaking Test
The spec './spec/models/foo_spec.rb' leaves
the following rows in the database:
- 1 row(s) for the Foo model
- 5 row(s) for the Bar model
#### What now?
If you are using let! or before(:all) please ensure that you use a
corresponding after(:all) block to clean up these rows.
..........
Finished in 3.14159 seconds
15 examples, 0 failures
Randomized with seed 17015
Ignoring Models
You may have some models that you don't want to report on, for example a configuration table that is seeded or loaded with fixtures as part of test suite setup.
config.after(:all) do
# Perform the report after each example group
DatabasePlumber.inspect ignored_models: [Bar, Baz]
end
Ignoring Databases
You may have models in your application backed by multiple adapters, some of which may be throw-away after each example group e.g. using SQLite for anonymous models
To exclude all models from a given adapter, you can add the following:
config.after(:all) do
# Perform the report after each example group
DatabasePlumber.inspect ignored_adapters: [:sqlite]
end
If you are unsure of which adapter to ignore, you can check via the Rails console:
> Foo.connection.adapter_name
'PostgreSQL'
# The corresponding symbol to use is :postgresql
Halting Tests on a Leak
When debugging a suite with several mystery guests, you can halt immediately after each leak.
config.after(:all) do
# Perform the report after each example group
DatabasePlumber.inspect ignored_models: [Bar, Baz],
ignored_adapters: [:sqlite],
brutal: true
end
Setting thresholds for Models
You may have some models you would like to report on, but which should also have entries in the database, for example a table that is seeded or loaded with fixtures. In order to allow this you can provide a threshold for a Model, which is the maximum number of entries allowed in the database for the Model before it is regarded as leaky.
To provide a threshold for a Model, you can can the following:
config.after(:all) do
# Perform the report after each example group
DatabasePlumber.inspect model_thresholds: { Bar => 3 }
end
## Contributing
1. Fork it ( https://github.com/brrygrdn/database_plumber/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
[rails]: https://github.com/rails/rails
[factorygirl]: https://github.com/thoughtbot/factory_girl
[databasecleaner]: https://github.com/DatabaseCleaner/database_cleaner
[capybara]: https://github.com/jnicklas/capybara
[rspec]: https://github.com/rspec/rspec