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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
1 514
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

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

Да, в этом примере это была просто ассоциация ActiveRecord. Я начал использовать Shoulda, который предоставляет помощники, такие как should_have_many: children, это значительно упрощает работу.

Daniel Beardsley 25.10.2008 20:47

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

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/…

Magne 24.10.2017 13:20
Ответ принят как подходящий

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

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

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

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

Это в сочетании с плагином Thinkbot rails Shoulda позволяет довольно легко запускать настройку и разборку для подгруппы методов тестирования, сохраняя ваш тестовый код DRY.

Daniel Beardsley 24.10.2008 05:15

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

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

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

После некоторой оптимизации я сократил требования до 150 или около того записей в 5 таблицах. Это приложение для анализа данных.

Daniel Beardsley 25.10.2008 20:49

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

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

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

should_have_many :children
should_belong_to :parent

Итак, вы воссоздали записи на основе производственных данных при каждом запуске тестов? Было ли это успехом?

Magne 24.10.2017 13:16

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