Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec - How to clean the database after each test

I have a feature spec with Capybara for a login page, and I am using FactoryGirl + DatabaseCleaner

require 'rails_helper'

feature 'Admin signs in' do

  background do
    FactoryGirl.create(:user)
  end

  scenario 'with valid credentials' do
    visit admin_root_path
    fill_in 'user_email', :with => '[email protected]'
    fill_in 'user_password', :with => 'testpassword'
    click_button 'Sign in'
    expect(page).to have_content('Dashboard')
  end

  scenario 'with invalid credentials' do
    visit admin_root_path
    fill_in 'user_email', :with => '[email protected]'
    fill_in 'user_password', :with => 'wrongpassword'
    click_button 'Sign in'
    expect(page).to have_content('Admin Login')
  end

end

running the test, I get the following error:

1) Admin signs in test with invalid credentials
 Failure/Error: FactoryGirl.create(:user)
 ActiveRecord::RecordInvalid:
   Validation failed: Email has already been taken

I thought DatabaseCleaner would revert the changes, but it looks like the user record persist in the database till the second scenario block.

How can I make sure that the database is cleaned after the first scenario?

I configured Database cleaner following this post

# support/database_cleaner_spec.rb

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

I have also updated the spec helper file with:

config.use_transactional_fixtures = false
like image 684
Carlo Avatar asked Apr 06 '15 07:04

Carlo


People also ask

Does RSpec clean database?

I use the database_cleaner gem to scrub my test database before each test runs, ensuring a clean slate and stable baseline every time. By default, RSpec will actually do this for you, running every test with a database transaction and then rolling back that transaction after it finishes.

Is RSpec TDD or BDD?

RSpec is a Behavior-Driven Development tool for Ruby programmers. BDD is an approach to software development that combines Test-Driven Development, Domain Driven Design and Acceptance Test-Driven Planning. RSpec helps you do the TDD part of that equation, focusing on the documentation and design aspects of TDD.

What is the difference between RSpec and cucumber?

The main difference between RSpec and Cucumber are the business readability factor. Cucumber's main draw is that the specification (features) are separate from the test code, so your product owners can provide or review the specification without having to dig through code.


2 Answers

I was wrongly assuming that configuration files in spec/support folder were automatically loaded, but it turns out that I had to uncomment the following line in spec/rails_helper.rb

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

The DatabaseCleaner config file was correct, it just wasn't loaded at all.

like image 187
Carlo Avatar answered Sep 23 '22 11:09

Carlo


Make sure you have the following configuration in spec/rails_helper.rb

RSpec.configure do |config|
 config.use_transactional_fixtures = true
end

The idea is to start each example with a clean database, create whatever data is necessary for that example, and then remove that data by simply rolling back the transaction at the end of the example.

like image 34
Rokibul Hasan Avatar answered Sep 22 '22 11:09

Rokibul Hasan