Explain & strengthen RSpec+Capybara config

The configuration is a tad more robust in 2 ways:

- It checks the Capybara driver isn't rack_test - this is the more reliable check. Using the `js: true` flag is only one of the ways in which a driver can be set. For example the `:driver` metadata option is an alternative way of setting the capybara driver.
- Setting `config.use_transactional_fixtures = false` in the database cleaner configuration is not always enough alone. If the config is still set in `rails_helper.rb` to `config.use_transactional_fixtures = true`, that can take precedence. The linked to configuration raises an error if this error is detected.
This commit is contained in:
Eliot Sykes 2015-07-14 17:30:56 +01:00
parent 82bcbde019
commit bba1bcce74

View file

@ -221,7 +221,30 @@ end
### RSpec with Capybara Example ### RSpec with Capybara Example
If you're using Capybara with RSpec and using an external browser (not using RackTest) you'll almost certainly need to use truncation rather than transactions for tests tagged `:js`. You'll typically discover a feature spec is incorrectly using transaction
instead of truncation strategy when the data created in the spec is not
visible in the app-under-test.
A frequently occurring example of this is when, after creating a user in a
spec, the spec mysteriously fails to login with the user. This happens because
the user is created inside of an uncommitted transaction on one database
connection, while the login attempt is made using a separate database
connection. This separate database connection cannot access the
uncommitted user data created over the first database connection due to
transaction isolation.
For feature specs using a Capybara driver for an external
JavaScript-capable browser (in practice this is all drivers except
`:rack_test`), the Rack app under test and the specs do not share a
database connection.
When a spec and app-under-test do not share a database connection,
you'll likely need to use the truncation strategy instead of the
transaction strategy.
See the suggested config below to temporarily enable truncation strategy
for affected feature specs only. This config continues to use transaction
strategy for all other specs.
```ruby ```ruby
RSpec.configure do |config| RSpec.configure do |config|
@ -229,11 +252,39 @@ RSpec.configure do |config|
config.use_transactional_fixtures = false config.use_transactional_fixtures = false
config.before(:suite) do config.before(:suite) do
if config.use_transactional_fixtures?
raise(<<-MSG)
Delete line `config.use_transactional_fixtures = true` from rails_helper.rb
(or set it to false) to prevent uncommitted transactions being used in
JavaScript-dependent specs.
During testing, the app-under-test that the browser driver connects to
uses a different database connection to the database connection used by
the spec. The app's database connection would not be able to access
uncommitted transaction data setup over the spec's database connection.
MSG
end
DatabaseCleaner.clean_with(:truncation) DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end end
config.before(:each) do |example| config.before(:each, type: :feature) do
DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction # :rack_test driver's Rack app under test shares database connection
# with the specs, so continue to use transaction strategy for speed.
driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
if !driver_shares_db_connection_with_specs
# Driver is probably for an external browser with an app
# under test that does *not* share a database connection with the
# specs, so use truncation strategy.
DatabaseCleaner.strategy = :truncation
end
end
config.before(:each) do
DatabaseCleaner.start DatabaseCleaner.start
end end