DB contents not reflected in view when using Capybara and Poltergeist

Asked 2 years ago, Updated 2 years ago, 88 views

With Poltergeist, the behavior of the Capybara test case is strange.

First of all, if you don't use Poltergeist, the Capybara test case is success.

before {create(:user)}
it's test'do
  visit root_path
  expect(page).to have_content 'You have one user'
end

In the tested view,

Users are <%=User.count%> people

The description is similar to .
I'd like to test JS, so

it 'test', js:true do

If so, the display will look like 0 users and the test will fail.
(Check page.save_screenshot)

It seems that the user created in before is not getting the view well.

expect(User.count).toeq1

The is successful, so the DB has been written to it.

The situation is the same with the capybara-webkit instead of the Poltergeist.
How can I pass the test?

javascript ruby-on-rails rspec capybara poltergeist

2022-09-29 22:33

2 Answers

In my translated e-book Introduction to Rails Testing with Everyday Rails-RSpec, the source code of the sample application is published on GitHub.
I'm using selenium-webdriver, not Poltergeist, but I have the same idea, so I'll give you an example code.

https://github.com/everydayrails/rails-4-1-rspec-3-0/blob/master/spec/rails_helper.rb

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

  config.after(:each)do
    DatabaseCleaner.clean
  end

  config.use_transactional_fixes=true

  # ...
end

use_transactional_fixes was set to true, but it was OK to set false or comment out (default is false).

Also, DatabaseCleaner.cleaning was introduced from version 1.3.0, so update the DatabaseCleaner as needed.

https://github.com/everydayrails/rails-4-1-rspec-3-0/blob/master/Gemfile

 group:test do
  # ...
  gem "database_cleaner", "~>1.3.0"
  # ...
end

The meaning of the configuration is listed in Introduction to Rails Testing with Everyday Rails-RSpec

.

What is this doing?The first thing I'm doing is specifying a strategy to use when setting up test data.In order to keep each test independent, transaction is specified here.As you can imagine, this is a strategy that uses database transactions.Then, you specify a trunk (truncation) in the table to clean all data.Finally, you specify when to start and end a transaction (this is before and after each example in the test suite) and when to perform a full deletion (this is after each example).

One more thing to do is create a file called spec/support/shared_db_connection.rb and write the following:

https://github.com/everydayrails/rails-4-1-rspec-3-0/blob/master/spec/support/shared_db_connection.rb

class ActiveRecord::Base
  mattr_accessor:shared_connection
  @@shared_connection=nil

  def self.connection
    @@ shared_connection ||retrieve_connection
  end
end
ActiveRecord::Base.shared_connection=ActiveRecord::Base.connection

The need for this configuration is also discussed in the book.

Why is this kind of change necessary?To put it bluntly, if you use Selenium, there will be differences in how you handle database transactions are handled.When running the test, both the Selenium web server and the test code must share the state of the data.Without DatabaseCleaner and the patches listed above, testing may occasionally fail due to improper post-test cleanup.

Everyday Rails also contains practical information about Rails testing, which is useful as a reference book for when you're in trouble.Please read it if you like.

Introduction to Rails Testing with Everyday Rails-RSpec


2022-09-29 22:33

Is use_transactional_fixes set to true in the RSpec configuration?

What it really means in Rails is "run every test method with in a transaction."

https://relishapp.com/rspec/rspec-rails/docs/transactions

If this setting is true, all tests are performed during a transaction.
Therefore, create(:user) is also executed during the transaction.
visit root_path in Capybara does not commit the create(:user) transaction, so no record has been created and 0 people are displayed.

If use_transactional_fixes is set to false, the test will pass.

However, in that case, you will need to manage your own actions, such as deleting the records that you created in the test.
You may want to use a combination of gems such as database_cleaner or database_rewinder to roll back the test records.


2022-09-29 22:33

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.