Rspec, Cucumber: best speed database clean strategy

后端 未结 4 1730
庸人自扰
庸人自扰 2021-02-05 14:17

I would like to increase the speed of my tests.

  1. Should I use use_transactional_fixtures or go with the database_cleaner gem?
  2. Whi
4条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-05 15:15

    1., 2. & 4., You should use transactions (either with use_transactional_fixtures or transactions support from the database_cleaner gem) if you are using capybara's default engine, rack_test. As you noted, using transactions are substantially faster than using a truncation strategy. However, when database writes can go through different threads (as with selenium) transactions won't work. So you'll need to use truncation (or force everything to go through one db thread--another option).

    3. Yes, you should turn off use_transactional_fixtures when using the database_cleaner gem since the gem natively support transactions. If you only need transactions then just use_transactional_fixtures and never load the database_cleaner gem.

    5. The following code will switch between :transaction and :truncation on the fly. (Tested this with rspec, capybara, rails3.)

    Features This should give you the best of both worlds. The speed of rack_test when you don't need to test javascript stuff and the flexibility of selenium when you do.

    Also this code takes care of repopulating seed data in cases where it is needed (this method assumes you use seeds.rb to load your seed data--as is the current convention).

    Add the following code to spec_helper.

    config.use_transactional_fixtures = false
    RSpec.configure do |config|
      config.before(:suite) do
        require "#{Rails.root}/db/seeds.rb"
      end
    
      config.before :each do
        if Capybara.current_driver == :rack_test
          DatabaseCleaner.strategy = :transaction
        else
          DatabaseCleaner.strategy = :truncation
        end
        DatabaseCleaner.start
      end
      config.after(:each) do
        if Capybara.current_driver == :rack_test
          DatabaseCleaner.clean
        else
          DatabaseCleaner.clean
          load "#{Rails.root}/db/seeds.rb"
        end
      end
    end
    

    Thanks Jo Liss for pointing the way.

    PS: How to switch drivers on the fly

    The above solution assumes you already know how to switch drivers on the fly. In case some who come here don't, here's how:

    As above let's assume that you normally will use the default capybara driver rack_test, but need to use selenium to test some Ajaxy stuff. When you want to use the selenium driver use :js => true or @javascript for Rspec or cucumber respectively. For example:

    Rspec example:

    describe "something Ajaxy", :js => true do
    

    Cucumber example:

    @javascript
    Scenario: do something Ajaxy
    

提交回复
热议问题