Почему не нужно писать тесты на визуал при разработке
Вопрос касается не только TDD-разработки, но и написания качественных unit-тестов в целом.
В прошлой заметке был тест на проверку отправки юзеру в бот ссылки для входа на сайт. Вот код (я еще про Argument::that() хотел отдельно написать):
Здесь мы проверяем, что пользователю в конце ушёл в виде сообщения определённый текст. Каковой текст и является визуалом, то есть представлением. Это вывод текста и кнопки-ссылки в форме телеграм-сообщения. И этот текст тестировать не нужно.
Почему? Потому что текст (представление) не является функциональной частью нашего решения. Мы можем написать какое угодно другое сообщение, но пока в нём содержится ссылка на логин, наша фича работает корректно. То есть конкретное содержимое текста совершенно не имеет значения.
Почему ещё? Потому что в ходе развития проекта мы текст можем много раз улучшить и переписать. Что повлечёт необходимость менять соответствующие тесты. Безо всякой на то нужды, поскольку кнопку и роут входа мы не меняли.
Иными словами, при написании тестов, будь то TDD, или просто тесты из общих соображений, мы тоже должны отделять бизнес-логику от представления. Тест — это не застывшее описание реализации, а спецификация поведения программы. А смена текста сообщения (представления) никак не меняет поведение (бизнес-логику). Поэтому тест не должен ломаться при смене текста.
Текст был бы уместен, если бы кроме него никаких проверяемых результатов у нашей фичи бы не было. И то, тогда лучше проверить не наличие конкретных букв, а название строки из массива локализаций. Тогда проверку в упомянутом тесте можно было бы переписать так:
Возвращаясь к Argument::that() — как вы уже могли заметить, этот статичный метод (из мок-библиотеки Prophecy) позволяет проверять в переданных аргументах только то, что действительно нужно проверить. А без него методы типа shouldHaveBeenCalled() будут проверять все аргументы на точное совпадение. Что сделает наши тесты очень деревянными.
Пример я взял из телеграм-бота просто потому что он был под рукой. Но абсолютно то же самое применимо и к веб-страницам. Не нужно, 10 раз не подумав, загонять в тесты конкретную верстку, или конкретные тексты. Нашим тестам от этого только вред: вывести фичу не поможет, а исправлять тесты потом придётся часто, причем безо всякой пользы для кода.
А для тестирования визуала есть более подходящие способы: инструменты, сравнивающие референсные страницы с заранее сохраненными скринами попиксельно и поднимающие шухер, если вдруг что-то куда-то съехало. Ghost Inspector, например.