Почему тест: единицы и тест: функционалы настаивают на запуске в среде разработки?

Я пытаюсь протестировать некоторые параметры, зависящие от среды (промежуточное ПО, чтобы быть конкретным, но это, похоже, не имеет значения), но у меня возникают проблемы с тем, чтобы тесты запускались в правильной среде. Симптомы:

  • Если я запустил ruby test/unit/my_test.rb, все будет хорошо, потому что в первую очередь требуется test/test_helper.rb, который устанавливает среду в "test", а затем загружает среду Rails.
  • Если я запустил rake test, первая партия (функционалы) работает нормально, но вторая партия (единицы) терпит неудачу. Ошибка состоит в том, что ENV['RAILS_ENV] каким-то образом становится не установленным между партиями, тогда config/environment.rb видит, что ни один не установлен, и использует значение по умолчанию "development". Окружающая среда верна в начале config/environment.rb и в начале блока конфигурации в этом файле, но неправильно до конца. Я могу сказать, используя puts или удалив config/development.rb, заставляя его не находить файл.
  • Если я запустил rake test:units, я получаю ту же проблему, что и вторая партия rake test (т.е. все сбой)
  • Если я запустил rake test:functionals, я получаю то же самое, что и для rake test:units
  • Если я запустил rake test RAILS_ENV=test или rake test:units RAILS_ENV=test или rake test:functionals RAILS_ENV=test, все в порядке!

Одна вещь, которую я пробовал, которая не работает вообще, такова:

# in Rakefile:
task :set_test_env { ENV['RAILS_ENV'] = 'test' }
Rake::Task[:test].prerequisites.unshift :set_test_env
# and similarly for other test tasks

Я даже попытался создать отдельную одну из этих задач :set_test_env для каждой тестовой задачи, чтобы я был уверен, что она будет вызвана перед каждым, а не только один раз. Еще нет кубиков. Он вызван, и среда в начале config/environment.rb верна, но что-то не так внутри.

У меня нет вызовов, чтобы установить ENV['RAILS_ENV'] в моем коде где угодно.

Ответ 1

Чтобы дать вам полный ответ, я должен был бы взглянуть на код, но я постараюсь дать вам некоторые подсказки, которые могут быть полезны.

Прежде всего rake test, а все остальные варианты (test:units, test:functionals и т.д.) работают следующим образом

  • Вызывается процесс рейка, а задача test выполняется в текущей среде (которая по умолчанию является разработкой), поэтому development.rb всегда читается.
  • Задача Rake вызывает тестовый загрузчик в отдельном дочернем процессе (вы можете проверить это с помощью ps или pstree), здесь находится источник test_helper.rb и среда для проверки.

Когда вы запускаете ruby test/unit/my_test.rb, первый шаг пропускается, поэтому похоже, что проблема там лежит. Может быть, вы что-то делаете в development.rb, у которого есть побочные эффекты для подпроцесса?

Ответ 2

Я почти всегда хочу заставить свои тесты запускать себя и свои предпосылки в "тестовой" среде, особенно когда ENV ['RAILS_ENV'] установлен на любой из стандартных значений по умолчанию (во избежание катастрофических аварий), но я также хотите иметь возможность запускать тесты, например, в среде с именем "v_2_0_maint_test" или что-то вроде этого, вызывая rake test:units RAILS_ENV=v_2_0_maint_test в командной строке.

Итак, у меня есть файл test_tasks.rake, который добавляет предварительное условие для каждой из тестовых задач, которые меня интересуют. Поскольку это предварительное условие добавлено, любые другие предпосылки (например, db: test: prepare, db: fixtures: load ) работают в одной среде. Это утверждает, что эффективность влияет только на те тесты, на которые вы хотите повлиять, и свои предпосылки.

namespace :test do |n|
  [ n[:units], n[:functionals], n[:integration] ].each do |t|
    t.prerequisites.unshift(:set_test_env_dammit)
  end

  task :set_test_env_dammit do |t|
    if [ nil, "", "development", "staging", "production" ].index ENV['RAILS_ENV']
      RAILS_ENV = "test"
    end
  end
end

Ответ 3

В верхней части файла test_helper.rb у меня есть код

ENV["RAILS_ENV"] = "test"

Если у вас нет этой строки, системная проблема будет выполняться в среде по умолчанию (то есть в разработке).

Ответ 4

Поиск по всему проекту RAILS_ENV и его вариантам. Посмотрите, задаете ли вы его в своем приложении или в своих тестах.

Кроме того, на какой платформе вы работаете? Можете ли вы запустить тесты на другой машине и посмотреть, совпадают ли результаты?

Если это относительно недавняя разработка, и вы используете RCS, например Git или SVN, вы должны просмотреть последние коммиты, и если вы специально используете Git, вы должны изучить Git разрез`ать. Если вы не используете RCS, вы должны быть.

Если это действительно новая проблема с приложением, то это, вероятно, проблема с вашей средой.

Какие плагины и драгоценные камни вы установили/настроили? Можем ли мы увидеть обратную линию?

Ответ 5

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

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

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

  • Задайте среду для разработки (только для целей трассировки)

    export RAILS_ENV = разработка

  • Удалите все строки, которые искусственно вызывать исключения в вашей среде файлы.
  • Добавьте следующую строку в конец каждый файл в config/environment

    puts "**** In #{ENV['RAILS_ENV']} environment config ****"
    
  • Добавьте следующую строку в test/test_helper.rb чуть ниже строки, которая устанавливает среду для проверки.

    puts "**** Loading test helper **** Environment = #{ENV['RAILS_ENV']}"
    
  • Запустите rake, используя параметр trace, чтобы наблюдать за выполнением задач с помощью трассировки текущей активной среды.

    rake -t test
    
  • Изучите вывод, чтобы определить, где ваша среда установлена ​​неправильно.
  • Запустите тесты еще раз, но на этот раз установите среду непосредственно перед запуском тестов, используя

    export RAILS_ENV = test

Если у вас действительно есть проблема, возможно, вам стоит опубликовать вывод rake -t с кодом трассировки.

Это результат моих тестов в совершенно новом проекте с минимальным тестированием. Вы заметите, что до запуска реальных тестов среда всегда "проверяет"

** Invoke test (first_time)
** Execute test
** Invoke test:units (first_time)
** Invoke db:test:prepare (first_time)
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
**** In development environment config ****
** Execute db:abort_if_pending_migrations
** Execute db:test:prepare
** Invoke db:test:load (first_time)
** Invoke db:test:purge (first_time)
** Invoke environment
** Execute db:test:purge
** Execute db:test:load
** Invoke db:schema:load (first_time)
** Invoke environment
** Execute db:schema:load
** Execute test:units
**** Loading test helper **** Environment = test
**** In test environment config ****
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
.
Finished in 0.071771 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
** Invoke test:functionals (first_time)
** Invoke db:test:prepare
** Execute test:functionals
**** Loading test helper **** Environment = test
**** In test environment config ****
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
.....
Finished in 0.133776 seconds.

5 tests, 6 assertions, 0 failures, 0 errors
** Invoke test:integration (first_time)
** Invoke db:test:prepare
** Execute test:integration