Тестирование рельсов:Приспособления, фабрики и магические числа

StackOverflow https://stackoverflow.com/questions/227973

Вопрос

У меня есть приложение, которому требуется довольно много данных (1000 записей) для проведения соответствующего тестирования.Единственный способ, который я нашел, чтобы получить приличный набор проверяемых, разумных данных, - это использовать подмножество моей производственной базы данных.Я преобразовал это в YAML fixtures в обычном расположении `test / fixtures'.

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

пример

def test_children_association
  p = Parent.find(1)
  assert_equal 18, p.children.count, "Parent.children isn't providing the right records"
end

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

Это было полезно?

Решение

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

Приспособления имеют некоторые проблемы, но есть несколько простых вещей , которые вы можете сделать , чтобы с ними было легче работать:

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

  2. Добавьте данные, подлежащие тестированию, в контексте теста.Это улучшает читаемость ваших тестов и избавляет вас от необходимости писать "убедитесь, что никто не перепутал приспособления" для проверки работоспособности в начале ваших модульных тестов.

Другие советы

Первое, что я бы сказал, это:что вы тестируете в этом примере?Если бы это была обычная ассоциация AR has_many, то я бы не стал утруждать себя написанием теста для нее.Все, что вы делаете, это тестируете, работает ли AR.

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

что я нашел наиболее полезным в этой ситуации, так это вообще не использовать приспособления, а скорее создавать объекты базы данных "на лету", например

def test_foo
   project = Project.create valid_project.merge(....)
   *do assertions here*
end

и в моих test_helpers у меня была бы куча методов:

def valid_project
   { :user_id => 23, :title => "My Project" }
end

def invalid_project
   valid_project.merge(:title => nil)
end

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

Кэмерон права:Что вы тестируете?

Какой системе требуется наличие 1000 записей для тестирования?Помните, что ваши тесты должны быть как можно более крошечными и должны тестировать поведение приложения.Для подавляющего большинства этих тестов ни в коем случае не нужны тысячи записей.

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

Возможно, у меня здесь уникальная ситуация, но мне действительно понадобилось довольно много записей для тестирования этого приложения (я сократил их до 150 или около того).Я анализирую исторические данные и располагаю многочисленными уровнями has_many.Некоторые из моих методов выполняют пользовательские SQL-запросы по нескольким таблицам, которые я мог бы в конечном итоге изменить для использования ActiveRecord.find но сначала мне нужно было запустить тест.

Во всяком случае, в итоге я использовал некоторые код ruby для создания приспособлений.Код включен в мой test_helper;он проверяет тестовую базу данных, чтобы увидеть, являются ли данные устаревшими (в зависимости от временного условия), и стирает и процедурно воссоздает записи.В этом случае его процедурное создание позволяет мне знать, для каких данных я тестирую СЛЕДУЕТ быть, которое есть безопаснее, чем использование подмножества производственных данных и надеюсь, что цифры, которые я вычислил в первый раз, - это то, что я должен проверить в будущем.

Я также перешел к использованию Следовало бы что наряду со многими другими полезными вещами делает тестирование ассоциации ActiveRecord таким простым, как:

should_have_many :children
should_belong_to :parent
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top