Search code examples
ruby-on-railsseleniumcapybarapoltergeistdatabase-cleaner

Rails clean database between tests not work


I'm new in rails. In my project i use rspec + capybara + poltergeist + selenium + database_cleaner.

Source code github link

I have postgresql 9.5.5, ubuntu 16.04 LTS.

When run test

rspec spec/controllers # everything work fine

When run

rspec spec/features # everything work fine too

But when i run all tests

rspec # part of tests fail

When run first acceptance test with :selenium -> question_id in browser 28, but must be 1, because it use database_cleaner.

Why database_cleaner not clean my database? What i do wrong? I spent a day to find a solution, but not found nothing. Help me please.

P.S. It's a training project.

My Database_Cleaner configuration is:

  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, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
    Warden.test_reset!
    if Rails.env.test?
      FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads"])
    end
  end

Solution

  • Cleaning the tables means it deletes all records, it doesn't necessarily mean it resets the index counters - just like if you delete record 3 and then add a new record - the new one would be 4. So in your case it's possible 27 records have been deleted and the next one you create would be 28 even though there's only 1 actual record. Query the database to see how many actual records are there to verify that.

    Next, your database cleaner config should be more like the recommended config - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example . append_after vs after is important for stability and checking the driver name vs just the :js metadata is too.

    When checking for the href '/uploads/attachment/file/1/test_file.dat' in your tests you shouldn't be checking for a hardcoded '1' there you should check based on the record id number of the record you created. So "/uploads/attachment/file/#{question.id}/test_file.dat" (obviously question.id will depend on what objects you've created and your variable names, but that matches at least one of your tests I think.

    Additionally after a quick look at your specs - anywhere you're doing expect(current_path).to eq ... is wrong. You should be doing expect(page).to have_current_path(...). The first way disables the retrying behavior of Capybara and will lead to flaky tests.

    And finally - where you have expect(page).not_to have_content t('common.button.ready'), I'm guessing that should be expect(page).not_to have_button t('common.button.ready')