Должны ли тесты модулей рельсов попасть в базу данных или нет? - PullRequest
3 голосов
/ 25 ноября 2010

Я писал тесты для своего приложения на рельсах.Я использую TestUnit для модульных и функциональных тестов.И я использую cucumber для тестирования GUI.

Но я обнаружил, что http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database говорит, что лучше для модульных тестов не попадать в базу данных.попадание в базу данных занимает значительное время.Я уже использую spork, чтобы уменьшить нагрузку на среду.

Какова наилучшая практика тестирования приложения rails?

Ответы [ 4 ]

19 голосов
/ 25 ноября 2010

Это один из случаев, когда вам не следует слишком зацикливаться на именах. Rails относится к тестам, в которых модели ActiveRecord используются как «модульные» тесты, в основном потому, что они являются тестами самого низкого уровня, непосредственно поддерживаемыми платформой. Согласно результатам тестирования, к которому, как я признаю, я склонен относиться довольно последовательно, модульные тесты не должны иметь зависимостей, внешних по отношению к тестируемому модулю; это означает такие вещи, как механизмы персистентности, то есть база данных.

Тем не менее, тестирование моделей ActiveRecord любой сложности без базы данных быстро заставит вас пожирать руки. Rails предполагает, что вы используете базу данных для тестов; это просто способ, которым написана структура. Вы можете попытаться заглушить все, но в конечном итоге потерпите неудачу, так как в конечном итоге вы будете возиться с внутренностями ассоциаций ActiveRecord (не для слабонервных). Вы можете попытаться извлечь весь код, не связанный с постоянством, в отдельные модули, которые тестируют без базы данных, но вы будете создавать довольно много ненужных сложностей.

Не пытайтесь бороться с рамками. ActiveRecord и ActionController имеют очень специфические шаблоны ожидаемого использования, как в производстве, так и в тестах. В конце концов, Rails - это все о конвенциях. Если вы будете следовать шаблону использования, вы будете выполнять гораздо меньше работы и будете гораздо меньше разочарованы, чем если вы будете бороться с соглашениями, чтобы придерживаться идеалов модульного тестирования. Если вам от этого легче, считайте, что ваши тесты ActiveRecord являются «модельными» тестами, а ваши функциональные тесты - «контролерными» тестами (это терминология, которая используется rspec, между прочим).

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

5 голосов
/ 25 ноября 2010

Юнит-тесты не должны попадать в базу данных. Они должны проверить, что методы работают должным образом, если правильные данные доступны (независимо от того, откуда эти данные поступают). Поэтому при необходимости вы должны заглушки / издеваться, чтобы гарантировать, что каждый модульный тест изолирован.

Однако интеграционные тесты (как вы могли бы написать, например, с помощью Cucumber ) должны связать весь стек MVC, и у тех, у кого нет оснований не обращаться к базе данных

1 голос
/ 14 февраля 2014

Аргумент, что это «способ Rails» для тестирования моделей с «модульными тестами, которые попадают в БД» - это то же самое, что сказать: «Ну, все прыгают с моста, может быть, я должен?».

Каждое соглашение Rails, которому вы следуете, должно быть серьезно проанализировано, потому что в ретроспективе «монолотические приложения Rails», если бы они следовали этому совету, у них было бы более 100 моделей с интеграционными тестами. Даже если вы пометили спецификации как медленные и быстрые, у вас нет модульных тестов для моделей в «быстрой» категории (если только вы их не написали, в этом случае, возможно, вы слишком много тестируете).

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

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

Я пытаюсь написать «спецификации запроса», которые попадают в БД из-за HTTP-запроса. И используйте их как мои "функциональные тесты". Каждый класс, который я пишу, будь то сервис, модель или что-то еще, имеет свои тесты для своих открытых методов (которые, очевидно, заглушают БД).

0 голосов
/ 25 ноября 2010

Используйте быструю базу данных в памяти для модульного тестирования. Если вы хотите протестировать «методы, запускаемые должным образом, если правильные данные доступны», лучше использовать набор данных, который очень похож на ваш реальный набор данных. База данных в памяти может содержать очень маленькие или довольно большие наборы данных, в зависимости от ваших потребностей. HSQLDB поддерживается ruby-on-rails и обычно используется для модульного тестирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...