Запретить тесту Rails удалять начальные данные

Я использую seed.rb для заполнения некоторых справочных данных модели состояния:

State.create :name => 'Alabama', :abbreviation => 'AL'
State.create :name => 'Alaska', :abbreviation => 'AK'
# ...

Хотя я не использую фикстуры состояния (поскольку это исходные данные для начала, я думаю, что было бы не СУХО дублировать это исключительно для тестов), среда тестирования Rails, похоже, удаляет все исходные данные состояния во время тестирования. (Я удаляю, воссоздаю, переношу и повторно заполняю тестовую базу данных и подтверждаю, что данные есть до запуска модульного теста.)

В результате это утверждение успешно выполняется в seed.rb, но не проходит однострочный тест:

assert_equal 51, State.all.size

1) Failure:
test_state_seeds_are_present(StateTest) [/test/unit/state_test.rb:24]:
<51> expected but was
<0>.
1 tests, 1 assertions, 1 failures, 0 errors

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

Записи состояния всегда удаляются. Есть ли способ сказать Rails, чтобы он просто убрал начальные данные? Нужно ли мне дублировать все данные в фикстурах, чтобы убедиться, что они перезагружаются? Если не считать крупных политических событий, я ожидаю, что данные о состоянии будут относительно стабильными.

Тиа


person aaron    schedule 14.12.2009    source источник
comment
Спасибо, ребята, я попробую как предложение Люка (одноразовое), так и предложение weppos (при настройке) для явной загрузки начальных данных в тесты и посмотрю, какое из них лучше всего подходит для моих целей. Я буду считать само собой разумеющимся, что тесты всегда сначала уничтожают данные БД.   -  person aaron    schedule 15.12.2009


Ответы (6)


Тесты удаляют все данные из базы данных, а затем загружают ваши приборы (если они у вас есть).

Вам нужно, чтобы ваш помощник по тестированию загружал начальный файл перед запуском тестов. Есть несколько способов сделать это, посмотрите мой аналогичный вопрос: Как автоматически загрузить данные db:seed в тестовую базу данных?

Самый простой способ, вероятно, просто добавить

require "#{Rails.root}/db/seeds.rb"

в начало файла test_helper.rb (при условии, что вы используете встроенную среду тестирования).

person Luke Francl    schedule 14.12.2009
comment
Это не работает для меня, если я добавлю эту строку в свой прибор, она будет работать нормально, но если я помещу ее в test_helper.rb, начальные данные, похоже, исчезнут до того, как будут достигнуты мои тесты. - person dangerousdave; 11.03.2010
comment
У вас есть yml-файл приспособления для класса, который вы пытаетесь заполнить в своем начальном файле? Потому что это сотрет все данные при запуске приборов. Удалить файл приспособления для семян; или, если вы не можете этого сделать, используйте пример Симоне, где данные прибора загружаются перед каждым тестом. - person Luke Francl; 11.03.2010
comment
ааа, я закомментировал свой файл .yml, но этого, похоже, недостаточно, простое его присутствие приводит к перезаписи начальных данных. Удалил, и все хорошо, спасибо Люк за помощь - person dangerousdave; 11.03.2010
comment
да, это немного нелогично, но если файл yml есть и пуст, он все равно удаляет содержимое этой таблицы. - person Luke Francl; 12.03.2010

Функция «seed» не интегрирована в тестовую архитектуру. Тесты построены вокруг фикстур, и каждый раз, когда вы запускаете набор тестов, Rails загружает данные из фикстур и заменяет существующее содержимое.

Однако заполнить базу данных исходными данными очень просто.

В файле test_helper.rb добавьте новый метод установки в базовый класс ActionSupport::TestCase.

class ActionSupport::TestCase < ...

  setup :load_seeds

  protected 

    def load_seeds
      load "#{Rails.root}/db/seeds.rb"
    end

end
person Simone Carletti    schedule 14.12.2009
comment
Это будет перезагружать ваши начальные данные перед каждым тестовым случаем, что, учитывая транзакционные фикстуры, вам, вероятно, не нужно делать. Пока начальные данные должны оставаться постоянными (что и должно быть), вам нужно загрузить их только один раз. - person Luke Francl; 14.12.2009
comment
Это то, о чем я думал, Люк, но, похоже, оно все равно удаляется, поэтому похоже, что мне придется реализовать какой-то обходной путь, чтобы убедиться, что он присутствует в базе данных для тестов. - person aaron; 15.12.2009
comment
У вас есть файл States.yml в вашем каталоге приборов? Даже если он пуст, это приведет к удалению данных о ваших состояниях. Я всегда удаляю фикстуры для своих таблиц начальных данных (на самом деле я вообще больше не использую фикстуры, но это уже другая история). - person Luke Francl; 15.12.2009
comment
Да, у меня есть или был файл States.yml (пустой). Его удаление (ну, переименование) было одной из попыток, которые я пробовал, но, похоже, это не помогло. Но я попробую еще раз, потому что мне все еще интересно посмотреть, смогу ли я предотвратить даже попытку удалить данные. - person aaron; 16.12.2009

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

Это можно сделать, выполнив в файле db/seeds.rb что-то вроде следующего:

RAILS_FIXTURES = "#{Rails.root}/spec/fixtures"

models_loaded_from_fixtures = %w[Modela Modelb Modelc ....]

models_loaded_from_fixtures.each do |model|
  Fixtures.create_fixtures(RAILS_FIXTURES, "#{model.tableize}")
  puts "Loaded #{model.constantize.all.size} #{model.pluralize}"
end

В качестве альтернативы вы можете прочитать каталог fixures и создать массив имен файлов для обработки, я выбрал описанный выше процесс, так как хотел иметь возможность указать, какие из моих многих существующих приспособлений я хотел бы заполнить БД.

person Steve Weet    schedule 14.12.2009

Я сомневаюсь в необходимости написания такого теста в первую очередь. Вы проверяете, правильно ли работает задача обработки начальных данных, или хотите проверить поведение своей реализации класса State? Я предполагаю последнее, поэтому я бы написал тесты, которые фокусируются на поведении и используют Factory Girl (или что-то подобное), поскольку вы упомянули, что не используете приборы. Обязательно удалите строку fixtures :all из test/test_helper.rb.

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

namespace :test do
  task :force_environment do
    ENV['RAILS_ENV'] = 'test'
    RAILS_ENV.replace('test')
  end
end

%w(test:units test:functionals test:integration).map do |task_name|
  task = Rake::Task[task_name]
  task.clear_prerequisites

  task.enhance %w(db:test:prepare test:force_environment db:seed)
end

Просто поместите это в файл с именем lib/tasks/testing.rake, и он будет выбран при следующем запуске rake test или другой задачи, связанной с тестом.

person Patrick Reagan    schedule 14.12.2009
comment
Привет, Патрик. На самом деле мне не нужно тестировать модель состояния как таковую, это был просто пример, демонстрирующий отсутствие начальных данных. Модель состояния (справочные данные) используется при проверке адресов, и тесты проверки адресов не удались, поскольку данных о состоянии не было в базе данных. - person aaron; 15.12.2009
comment
Это имеет больше смысла. Задача Rake должна работать для вас, но похоже, что у вас все работает. - person Patrick Reagan; 16.12.2009

У меня была такая же проблема, но стандартный ответ мне не помог.

Моя проблема заключалась в местах в файлах классов, которые выполняли поиск в базе данных констант и named_scopes. Я не мог найти способ загрузить начальные данные в нужное время.

Я нашел способ обойти удаление, которое происходило, несмотря на то, что я удалил свой файл фиксации для отсутствующей таблицы.

RAILS_ENV=test rake db:seed ruby ​​-Itest test/units/*.rb

person Marlin Pierce    schedule 03.10.2011

Вы не можете применить оба параметра seed и fixtures для настройки одних и тех же данных table по умолчанию.

например. Если вы настроите прибор с именем products.yml, он "удалит данные из продуктов" при создании fixtures.

Ты сможешь:

  1. Переместить сцену seed за fixturess (загрузить начальное число вручную);
  2. Используйте только один из них или альтернативный подход к управлению тестовыми данными;
  3. Не используйте оба подхода для настройки данных одной и той же таблицы;
  4. В Rails4.2 вы можете взломать этот строка в вашем test_helper.rb следующим образом:

>

require 'rails/test_help'

class ActiveRecord::FixtureSet
  def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
    ...
    # table_rows.each_key do |table|
    #   conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
    # end
    ...
  end

Это помогло бы в некоторых устаревших случаях, но перепутывание seeds и fixtures может привести к новым проблемам.

person pokka    schedule 20.04.2018