Почему мои тесты замедляются после обновления рельсов от 3,1 до 3,2?

Я выполнил следующие инструкции по обновлению: http://railscasts.com/episodes/318-upgrading-to-rails-3-2

Вот мои три небольших обновления:

(1) Gemfile

-gem 'rails', '3.1.0'
+gem 'rails', '3.2.0'

-gem 'rack', '1.3.3'
+#gem 'rack', '1.3.3'

 group :assets do
-  gem 'sass-rails', '  ~> 3.1.0'
-  gem 'coffee-rails', '~> 3.1.0'
-  gem 'uglifier'
+  gem 'sass-rails', '  ~> 3.2.3'
+  gem 'coffee-rails', '~> 3.2.1'
+  gem 'uglifier', '     >=1.0.3'
   gem 'asset_sync'
 end

(2) config/environment/development.rb

+  config.active_record.mass_assignment_sanitizer = :strict
+  config.active_record.auto_explain_threshold_in_seconds = 0.5

(3) config/environment/test.rb

-  config.assets.allow_debugging = true
+  config.active_record.mass_assignment_sanitizer = :strict

До обновления мои тесты выглядели следующим образом (ну под каждым секундой):

...
StockroomTest:
     PASS stockroom must have a name (0.03s) 
     PASS stockroom name must be unique (0.01s) 
     PASS stockroom with name is valid (0.00s) 
...
Finished in 1.604118 seconds.
29 tests, 90 assertions, 0 failures, 0 errors, 0 skips
...
StockroomsControllerTest:
     PASS should create stockroom (0.04s)
     PASS should destroy stockroom (0.02s)
     PASS should get edit (0.14s)
     PASS should get index (0.11s)
     PASS should get new (0.03s)
     PASS should not destroy stockroom (0.04s)
     PASS should show stockroom (0.13s)
     PASS should update stockroom (0.02s)
...
Finished in 12.572911 seconds.
115 tests, 166 assertions, 0 failures, 0 errors, 0 skips
...
MiscellaneousTest:
     PASS get campaigns#index should redirect to newsletters#index (1.83s)
     PASS get /campaigns should redirect to / when logged out (0.06s)
Finished in 1.793070 seconds.
2 tests, 3 assertions, 0 failures, 0 errors, 0 skips

После (каждый тест занимает более 1 секунды):

StockroomTest:
     PASS stockroom must have a name (1.29s)
     PASS stockroom name must be unique (1.30s)
     PASS stockroom with name is valid (1.27s)
...
Finished in 41.135808 seconds.
29 tests, 90 assertions, 0 failures, 0 errors, 0 skips
...
StockroomsControllerTest:
     PASS should create stockroom (1.30s)
     PASS should destroy stockroom (1.29s)
     PASS should get edit (1.33s)
     PASS should get index (1.43s)
     PASS should get new (1.41s)
     PASS should not destroy stockroom (1.31s)
     PASS should show stockroom (1.36s)
     PASS should update stockroom (1.31s)
...
Finished in 161.803235 seconds.
115 tests, 166 assertions, 0 failures, 0 errors, 0 skips
...
MiscellaneousTest:
     PASS get /campaigns should redirect to /newsletters when logged in (5.27s)
     PASS get /campaigns should redirect to / when logged out (1.67s)
Finished in 7.034593 seconds.
2 tests, 3 assertions, 0 failures, 0 errors, 0 skips

Ниже приведен пример одного из модульных тестов сверху. Это займет около 1,3 секунд для запуска (после обновления), по сравнению с менее чем 0,01 с ранее.

тест/блок/stockroom_test.rb

require 'test_helper'

class StockroomTest < ActiveSupport::TestCase
  fixtures :stockrooms

  test "stockroom with name is valid" do
    assert stockrooms(:wine_cellar).valid?, 'tried new wine_cellar'
  end

Я знаю, что светильники нахмурились, и я намерен серьезно заглянуть в фабрики, но пока это мое затруднительное положение. Вот соответствующее приспособление:

тест/светильники/stockrooms.yml

wine_cellar:
  id: 1
  name: wine cellar

Только две проверки на Stockroom: presence и uniqueness.

Примечание. Я запускаю другое приложение rails на той же машине, хотя он работает с рельсами 3.2.5, и почти идентичный unit test (то же утверждение на тех же двух проверках) заканчивается в 0.465489 секунд (меньше половины второй).

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

 (0.9ms)  SET FOREIGN_KEY_CHECKS = 1
 (0.2ms)  BEGIN
 (84.8ms)  BEGIN
 (82.3ms)  BEGIN
 (83.4ms)  BEGIN
 (79.2ms)  BEGIN
 (82.1ms)  BEGIN
Stockroom Load (0.4ms)  SELECT `stockrooms`.* FROM `stockrooms` WHERE `stockrooms`.`id` = 1 LIMIT 1
Stockroom Exists (0.6ms)  SELECT 1 AS one FROM `stockrooms` WHERE (`stockrooms`.`name` = BINARY 'wine cellar' AND `stockrooms`.`id` != 1) LIMIT 1
 (0.1ms)  ROLLBACK
 (90.9ms)  ROLLBACK
 (85.7ms)  ROLLBACK
 (90.7ms)  ROLLBACK
 (81.4ms)  ROLLBACK
 (85.4ms)  ROLLBACK

И для сравнения, здесь "эквивалентный" тест в моих рельсах 3.2.5 app:

 (0.2ms)  SET FOREIGN_KEY_CHECKS = 1
 (0.1ms)  BEGIN
Email Load (0.4ms)  SELECT `emails`.* FROM `emails` WHERE `emails`.`id` = 980190962 LIMIT 1
Email Exists (2.8ms)  SELECT 1 FROM `emails` WHERE (`emails`.`email` = BINARY 'MyString' AND `emails`.`id` != 980190962) LIMIT 1
 (0.2ms)  ROLLBACK

Ответ 1

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

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

Если это так, вы можете найти свой ответ здесь: Откат ActiveRecord не работает в тесте Rails

Только вы можете попытаться включить функцию явно.

Изменить: поскольку ваш вывод показывает, что вы используете транзакции, может быть разница в том, как загружается среда рельсов. Пожалуйста, проверьте spec_helper.rb для странных различий.

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