DatabaseCleaner đảm bảo mỗi test bắt đầu với DB sạch — tránh test state rò rỉ sang test khác.
Ba strategy chính:
| Strategy | Cơ chế | Tốc độ | Dùng khi |
|---|---|---|---|
transaction | Wrap test trong transaction, rollback sau | Nhanh nhất | Unit/request test không cần JS |
truncation | TRUNCATE tất cả bảng | Chậm | System test (Capybara + JS), cần data persist |
deletion | DELETE FROM từng bảng | Trung bình | Ít dùng |
ruby
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) { DatabaseCleaner.strategy = :transaction }
config.around(:each) { |ex| DatabaseCleaner.cleaning { ex.run } }
# System tests cần truncation vì Capybara dùng thread riêng
config.before(:each, type: :system) { DatabaseCleaner.strategy = :truncation }
endRSpec transactional fixtures (use_transactional_fixtures: true) cũng làm được điều tương tự nhưng DatabaseCleaner linh hoạt hơn khi mix nhiều loại test.