Подтвердить что ты не робот

Rspec, Cucumber: лучшая скорость базы данных.

Я хотел бы увеличить скорость моих тестов.

  • Должен ли я использовать use_transactional_fixtures или идти с камнем database_cleaner?
  • Какая стратегия database_cleaner лучше? Я заметил, что после перехода от :truncation до :transaction мои более 800 примеров выполняются примерно в 4 раза быстрее!
  • Должен ли я отключить use_transactional_fixtures, когда я использую database_cleaner :transaction?
  • Верно ли, что наилучшей стратегией для rack_test является :transaction?
  • Каковы наилучшие методы для изменения стратегии "на лету" от :transaction до :truncation при использовании селена или akephalos?

P.S. Mysql, Rails 3, Rspec2, огурец

P.P.S. Я знаю о spork и parallel_test и используя их. Но они оффтопичны. Например, Spork экономит около 15-20 секунд при запуске всего пакета, но изменение от :transaction до :truncation резко увеличивает время работы от 3,5 до 13,5 минут (разница в 10 минут).

4b9b3361

Ответ 1

1., 2. и 4... Если вы используете двигатель по умолчанию capybara, rack_test, вы должны использовать транзакции (либо с поддержкой use_transactional_fixtures, либо поддержкой транзакций из драгоценного камня database_cleaner). Как вы отметили, использование транзакций значительно быстрее, чем использование стратегии усечения. Однако, когда записи базы данных могут проходить через разные потоки (как с селеном), транзакции не будут работать. Таким образом, вам нужно будет использовать усечение (или заставить все переходить через один поток db - другой вариант).

3. Да, вы должны отключить use_transactional_fixtures при использовании драгоценного камня database_cleaner, поскольку драгоценный камень поддерживает транзакции. Если вам нужны транзакции, просто используйте use_transactional_fixtures и никогда не загружайте драгоценный камень database_cleaner.

5. Следующий код будет переключаться между :transaction и :truncation на лету. (Протестировано с помощью rspec, capybara, rails3.) ​​

Особенности. Это должно дать вам лучшее из обоих миров. Скорость rack_test, когда вам не нужно проверять содержимое javascript и гибкость selenium, когда вы это делаете.

Также этот код заботится о повторной заселенности семенных данных в случаях, когда это необходимо (этот метод предполагает, что вы используете seeds.rb для загрузки ваших данных семени - как и в текущем соглашении).

Добавьте следующий код в 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

Спасибо Jo Liss за то, что указали путь.

PS: Как переключать драйверы на лету

В приведенном выше решении предполагается, что вы уже знаете, как переключаться с драйверами "на лету". В случае, если кто-то сюда сюда не делает, вот как:

Как указано выше, предположим, что вы обычно будете использовать драйвер capybara по умолчанию rack_test, но вам нужно использовать селен для тестирования некоторых материалов Ajaxy. Если вы хотите использовать драйвер selenium, используйте :js => true или @javascript для Rspec или огурца, соответственно. Например:

Пример Rspec:

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

Пример огурца:

@javascript
Scenario: do something Ajaxy

Ответ 2

Использование транзакционных приборов будет быстрее, так как СУБД не фиксирует изменения (и, следовательно, не происходит тяжелая IO-перезагрузка базы данных между тестами), но, как вы знаете, не всегда будет работать.

У нас был некоторый успех с использованием баз данных SQLite в памяти в тестовой среде, поэтому тесты выполняются очень быстро, оставив транзакционные светильники выключенными. Эта опция также доступна для MySQL (используйте: опции для установки "ДВИГАТЕЛЬ = ПАМЯТЬ" ), но я никогда не делал этого лично, и если вы будете искать, вы найдете несколько потоков о связанных с ними предостережениях. Возможно, стоит посмотреть. В зависимости от вашей методологии тестирования может быть неприемлемо использовать другой механизм БД.

Я предлагаю вам включить транзакционные светильники и использовать DatabaseCleaner для выборочного отключения транзакционных светильников в группе примеров. Я не могу сказать, что я пробовал это, но поскольку у вас не было ответов, я понял, что что-то может помочь вам.

before(:all) do
  DatabaseCleaner.strategy = :transaction
  DatabaseCleaner.clean_with(:truncation)
end

before(:each) do
  DatabaseCleaner.start
end

after(:each) do
  DatabaseCleaner.clean
end

Если бы это был я, я бы включил это в помощника и назвал его как однострочный макрос из каждой примерной группы, для которой отключены транзакционные приборы.

Похоже, что действительно должен быть лучший способ, хотя.... удачи.

Ответ 3

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

Это из Avdi Grimm post об очистке базы данных и Rspec. Пошаговый анализ кода приведен в статье.

Ответ 4

Вы использовали Spork? Это значительно увеличивает скорость.