2016-03-08 3 views
0

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

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

Это что-то, что может быть (или сделано)? До сих пор мои поиски привели меня к большому количеству интересного чтения, но не к драгоценному камню, подобному этому ...

+0

Если вы просите людей найти стороннюю библиотеку, чтобы делать то, что вы хотите, пожалуйста, имейте в виду, что такие запросы не относятся к теме переполнения стека. Дополнительную информацию см. В [Файл справки переполнения] (http://www.stackoverflow.com/help). Если вы просто спрашиваете, возможно ли то, что вы хотите, я уверен, что это так. Возможно, это может быть драгоценный камень, который вы готовы внести в сообщество. – MarsAtomic

ответ

2

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

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

Вне тестирования вы можете захотеть взглянуть на линкер. По сути, вы спрашиваете, можете ли вы поймать ошибку, когда параметры, переданные методу объекта, не соответствуют сигнатуре. Это более увлекательно при полном анализе кода (т. Е. Компиляции в среде статического типа).

EDIT - я пропустил шаг на листинге, так как вам также нужно будет написать свой код определенным образом, чтобы линтер поймал его, например, более явным образом переданного ему метода и параметров.

+0

Очень хорошо написан ответ. Я действительно не вижу, как linter поможет в этом случае, хотя, поскольку вы в основном смотрите на кучу методов ActiveRecord, которые все принимают '(hash = {}, & block)', хотя линтеры, такие как Rubucop, хорошо разбираются в плохих практиках и обычных кодирования. – max

+1

Я хотел предложить возможный автоматический способ поймать подобные ошибки «бесплатно», что и требовалось OP, и сначала имел во внимание код анализа linter. Я думаю, что я предлагал это скорее как путь к исследованию, если бы ОП был незнакомым. Решением, которое я имел в виду, было изменение стилей кодирования и более явное, например определение собственных методов сохранения с явными параметрами. В этом случае linter может поймать, если вы не передаете правильное количество параметров. По общему признанию, это привело бы к шаблону кода и выглядело бы более Java-esque, поэтому ... не Rails вообще. –

1

Возможно, вам стоит подумать, что такой драгоценный камень может не существовать, потому что его не так практично или полезно в реальной жизни.

Получение столбцов от модели довольно просто из методов отражения, которые дает вам Active Record. И да, вы можете использовать это теоретически для автоматического запуска кучи тестов в цикле.

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

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

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

class ArticlesControllerTest < ActionController::TestCase 

    def valid_attributes 
    { 
     title: 'How to test like a Rockstar', 
     content: 'Bla bla bla' 
    } 
    end 

    test "created article should have the correct attributes" do 
    post :create, article: valid_attributes 
    article = Article.last 

    valid_attributes.keys.each do |key| 
     assert_equals article[key], valid_attributes[key] 
    end 
    end 
end 
Смежные вопросы