У меня есть приложение, которому требуется довольно много данных (тысячи записей) для проведения соответствующего тестирования. Единственный способ получить достойный набор проверяемых и разумных данных - это использовать подмножество моей производственной БД. Я преобразовал это в фикстуры YAML в обычном месте `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
Мне это не кажется хорошей идеей, но Я не уверен, есть ли лучший / приемлемый способ для тестирования приложения, которому требуется большая иерархия данных.





Первое, что я скажу: что вы тестируете в этом примере? Если это обычная ассоциация 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
Я обнаружил, что боль, связанная с необходимостью создания огромных коллекций тестовых объектов, естественным образом побудила меня разработать более простые и универсальные структуры классов.
Это было бы эквивалентно (но немного менее элегантно) использованию приборов, а затем Model.update_attributes в тесте, что предлагает DHH: david.heinemeierhansson.com/2014/…
Магические числа в тестах не являются антипаттерном. Ваши тесты должны быть настолько простыми, что вам не нужно их тестовое задание. Это означает, что у вас будут магические числа. Это означает, что ваши тесты сломаются, если вы измените небольшие части функциональности. Это хорошо.
Светильники имеют некоторые проблемы, но есть несколько простых вещей, которые вы можете сделать, чтобы с ними было легче работать:
В ваших приборах должны быть только базовые данные, которые нужны большинству ваших тестов, но не важны. Это потребует предварительных затрат времени, но лучше снять боль пораньше, чем писать плохие модульные тесты на всю жизнь проекта.
Добавьте данные для тестирования в контексте теста. Это улучшает читаемость ваших тестов и избавляет вас от написания проверок работоспособности «убедитесь, что никто не испортил приспособления» в начале ваших модульных тестов.
Это в сочетании с плагином Thinkbot rails Shoulda позволяет довольно легко запускать настройку и разборку для подгруппы методов тестирования, сохраняя ваш тестовый код DRY.
Кэмерон права: что вы тестируете?
Какой системе нужны тысячи записей для тестирования? Помните, что ваши тесты должны быть как можно меньше и должны проверять поведение приложения. Для подавляющего большинства этих тестов не нужны тысячи записей.
Для небольших тестов поведения, где вам нужны отношения между объектами, рассмотрите фиктивные объекты. Вы только укажете точный минимальный объем поведения, необходимый для прохождения вашего теста, и они вообще не попадут в БД, что приведет к огромному увеличению производительности в вашем наборе тестов. Чем быстрее он будет работать, тем чаще люди будут его запускать.
После некоторой оптимизации я сократил требования до 150 или около того записей в 5 таблицах. Это приложение для анализа данных.
У меня может быть уникальная ситуация, но мне действительно нужно было довольно много записей для тестирования этого приложения (я снизил их до 150 или около того). Я анализирую исторические данные и имею множество уровней has_many. Некоторые из моих методов выполняют пользовательские SQL-запросы к нескольким таблицам, которые я мог бы изменить для использования ActiveRecord.find, но мне нужно было сначала запустить тест.
Так или иначе, я использовал рубиновый код для создания светильников. Код есть в моем test_helper; он проверяет тестовую базу данных, чтобы увидеть, не устарели ли данные (в зависимости от времени), и стирает и процедурно воссоздает записи. В этом случае создание его процедурно позволяет мне узнать, какие данные я тестирую для ДОЛЖЕН, то есть безопаснее, чем использование подмножества производственных данных, и надеюсь, что числа, которые я вычисляю в первый раз, - это то, что я должен проверить в будущем.
Я также перешел на использование Следует, которое, наряду со многими другими полезными вещами, делает тестирование ActiveRecord Association таким же простым, как:
should_have_many :children
should_belong_to :parent
Итак, вы воссоздали записи на основе производственных данных при каждом запуске тестов? Было ли это успехом?
Да, в этом примере это была просто ассоциация ActiveRecord. Я начал использовать Shoulda, который предоставляет помощники, такие как should_have_many: children, это значительно упрощает работу.