Pull to refresh

Comments 25

Интересно, надо будет попробовать, а то я из числа тех, кто «обычно не прибегают к unit-тестированию контроллеров, обычно вообще тестирования не происходит». Модельки погонять (да и то без репозиториев) — это святое, а вот контроллеры…

Вот только не понял, вводим переменную templating, инициализируем её mock'ом, запускаем тест, происходит вызов в action, всё ок. А вот как эта переменная получит значение (и какое) при вызове обычным для симфони путём?
статья отвратительна.
Человек не понимает разницу между unit-тестированием и функциональным (приемочным) тестировании.
Он выдумал три недостатка приемочного тестирования. Контраргументы:
1. Конечно нужно запустить все ядро, ведь в этом и суть приемочного тестирование — тестируется работа всей системы в целом.
2. Конечно чувствительны. тесты пишутся с учетом спецификации, если эти изменения в дизайне не прописаны в спецификации — тесты должны это показать
3. Долго, но никто их и не запускает каждые 5 минут, а только, например, перед релизом.

Далее он предлагает использовать магический трюк в симфони чтобы сделать лишь что? протестировать внутренности метода контроллера! но зачем?? Это useless tests.
вообще речь не идет о том зачем, это для себя решает каждый сам в процессе реализаций той или иной задаче, в посте показано КАК, как это можно сделать в symfony2
возможно кто-то видит в этом смысле (я жду пока кто-нибудь объяснит его). я лишь не понимаю зачем говорить что «это» является заменой приемочных тестов, которые, по словам авторам, медленные и «вчерашний день».
думаю, что эти слова --«это» является заменой приемочных тестов, которые, по словам авторам, медленные и «вчерашний день»-- вряд ли авторства skorney
Смысл — быстро (без запуска всего ядра) и без зависимости от дизайна (вернее представления) и других связей протестировать логику контроллера, чтобы потом, когда на тех же условиях сфейлит функциональный (он же интеграционный) тест, быть уверенным, что уж в контроллере-то у нас всё ок.
И где вы нашли, что «это» является заменой функциональных тестов? Это вариант простой (относительно)реализации модульных тестов. Теперь перед запуском функциональных я буду проводить модульные и на котроллерах, потому что раньше не знал, как изолировать контроллер от представления в symfony.
>Далее он предлагает использовать магический трюк в симфони чтобы сделать лишь что? протестировать внутренности метода контроллера! но зачем?? Это useless tests.

Как зачем? А если там ошибка? :-/
какая ошибка?
как-то три слепых мудреца пошли посмотреть на чудо-юдо невиданное, на слона. пришли и давай расспрашивать что же он из себя представляет. первый узнал что он серый, второй узнал что у него большие уши, третий узнал что у него маленький хвост. и ушли огорчённые мудрецы, подумав что слон тоже самое что и заяц.
Даже в этом примитивном случае может быть, что, например, контроллер рендерит другой шаблон, рендерит нужный, но несколько раз, или вообще его не рендерит.
Для этого есть приемочные тесты, в которых не надо зорко бдить за соответствие моков остальному коду. Моки вообще зло, они дают ложную уверенность отсутствия багов.
Приёмочные тесты, имхо, своим названием намекают, что они плохо годятся для запуска каждые 5 минут, они хороши именно для сдачи/приёмки, но несут мало полезной для отладки информации в случае фейла. А ложную уверенность дают любые выполняющиеся тесты ;)
Юнит тесты с моками в этом плане только хуже. Приемочный тест даст вам сигнал, что ошибка есть. Если вы забыли синхронизировать протокол мока с живым объектом, то о ошибке вы даже не узнаете. Про тестирование контроллеров вообще, я склоняюсь к мнению, что они быть настолько простыми, чтобы их не надо было тестировать.
"… протестировать внутренности метода контроллера… ...useless tests."

Как это так useless???
автор показывает testIndexAction, в этом тесте есть мок (который показывает как работает indexAction внутри. И кстати, мелочь, но уже в таком простом примере конфигурация мока заняла 5 строк, в сложных проектах, когда в шаблоны передаются переменные, когда один метод возвращает разные форматы и т.п., этот мок займет экран). И завершается этот метод $this->assertEquals('success', $controller->indexAction()); который максимум протестировал что мок был сконфигрурирован правильно. И вы можете с некоторой уверенностью сказать что ваш indexAction работает без «ошибок»? Я — нет.
Этот тест демонстрирует, что шаблон вызывается с нужными параметрами, а не что мок был правильно сконфигурирован. Другой тест (для другого контроллера) покажет, что если id какой-то сущности, переданный контроллеру как параметр, есть в хранилище, то шаблону эта сущность передастся. Третий тест покажет, что если сущности с этим id нет в хранилище, то вместо вызова шаблона выбрасывается исключение HTTPNotFound…

Статья не о том, что функциональное тестирование не нужно, а о том как проводить модульное тестирование контроллеров symfony2. Или может вы считаете, что unit tests в принципе useless?

если разбирать конкретно этот пример, то вопрос. кто определяет список «нужных параметров»? я добавлю в шаблоне вызов неизвестной переменной. Сайт поломается, а тесты скажут всё OK. И наоборот, удалив переменную из шаблонов, тесты не сообщат о неиспользованной переменной. Т.е. все, о чем они будут сообщать нам, это о том, когда мы удалили/добавили переменные непосредственно в методе. Вот поэтому я считаю что useless.
Да, хранилище это тоже сервис, как и реквест, респонс, формы. Уже представляете сколько уйдет времени чтобы написать нужные моки?
Откуда я взял что автор считает его способ заменой функциональных тестов? Зачем тогда начинать статью про то как ужасны функциональные тесты и в идеальном мире ..?
Выше, про то, что такое ошибка я спросил не просто так. «контроллер рендерит другой шаблон, рендерит нужный, но несколько раз, или вообще его не рендерит. » — все это покажут функциональные тесты. testIndexAction is useless again.

PS: Symfony2 мне очень нравится и хочется чтобы фреймворк оставался таким же простым как сейчас, без этих «всё — сервисы». И нет, я считаю что unit tests конкретно для контроллеров useless.
Юнит-тесты контроллера и не должны показывать ошибки в шаблоне, шаблон это другой юнит, а вот если вы забудете вызвать шаблон, то тесты покажут ошибку. То, что в шаблоне есть неназначенная в контроллере переменная как раз зона ответственности интеграционных тестов, а юнит тесты и не должны показывать такие ошибки. С хранилищем проще, по-моему, использовать простенькое хранилище в памяти, реализующее нужные интерфейсы (стаб, а не мок).

Он, имхо, считает этот способ хорошей заменой использованию функциональных тестов приложения в качестве юнит-тестов контроллера (или вообще их нетестированию), что не стоит стрелять из пушки по воробьям и не стоит вообще не стрелять только лишь из-за желания экономить заряды пушки, если есть «мелкашка». Зачем стрелять по воробьям, по каждому ли или же только по особо упитанным каждый решает сам, в статье лишь описание процесса стрельбы. Представьте себё её название в виде «Как стрелять по воробьям из мелкашки», а начало как «Стрелять по воробьям из пушки неэффективно, лучше взять мелкашку» (а ваше useless как «да зачем по ним вообще стрелять, у нас есть пушка, давайте стрелять по слонам» :) )

А функциональные тесты не покажут, что шаблон вызывался дважды, если данные первого (или второго) вызова не будут возвращены в ответе. Также они не покажут, что данные действительно рендерятся (происходит вызов шаблонизатора), а не захардкодены в контролере. Ну и не покажут, что вызывался другой шаблон, если в нём тоже есть '/My Cool Website/'. Надо это показывать или нет, если ответ всё равно ожидаемый — отдельный холивар :)
UFO just landed and posted this here
Уверяю вас, автор хорошо понимает разницу unit-тестирования и функционального, но не в этом суть.
А вы думаете что все контроллеры одинаковые? и что их тестировать не нужно? Топик написал разработчик фреймворка — для разработчиков это очень нужно.

Термин POPO автор придумал сам? Просто если есть у нас есть Plain Old PHP Objects, то видимо должны быть и Enterprice PHP Beans? :)
В контроллерах не должно быть такого количества когда, чтобы его захотелось протестировать модульными тестами. Хочешь юнит-тест? Пиши сервис, стратегию, etc.
Объясните мне, плз, зачем нужно тестировать контроллеры?
Нет, я понимаю, тестировать модель — поменял в одном месте, проверил в другом, а ошибка вылезла в третьем (о котором забыл) — такое действительно хотелось бы отсекать.
А с контроллером что? Поменял его — и ничего, кроме его собственной работы, не поменялось. Не проще ли в таком случае тупо зайти на конкретную страницу/ы и проверить — все ли так (ведь все равно будем это делать, чтобы хотя бы внешний вид оглядеть). Нет, я не спорю, если это можно было бы сделать автоматом — было бы благо. Однако, когда мы можем лишь проверить, запустилось ли в принципе (по-сути, это все) — получается, что мы больше кода пишем для проверки…
Я может тут буду не совсем прав, но когда переводил, думал так. Я вроде понял о чем вы — контроллеры отвечают за отклик на конкретные параметры, они не так важны как модели, можно не тестировать. В общем да. НО! Вы смотрите как пользователь фреймворка. А статья от контрибутора кода в фреймворк, находящийся в стадии Preview Release. Когда вы вносите любые правки в код фреймворка — вы должны добиться прохождения всех unit-тестов. Я думаю автор просто хотел добавить тестов еще и на механизм контроллеров (который входит в состав фреймворка). Просто чтобы сделать будущие правки фреймворка более безопасными. Я думаю просто поднимается тема — почему не тестировать? — давайте и контроллеры тестировать. Еще этим переводом я хотел подчеркнуть, что в разработке на sf2 очень важно придерживаться TDD- так как фреймворк находится в активной стадии разработки.
Аааа! Ну, тогда ясно. Спасибо. С таким объяснением согласен.
Sign up to leave a comment.

Articles