Как стать автором
Обновить

Комментарии 8

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

Спасибо за обратную связь!)

Все ж очень просто — тестировать надо какой то устоявшийся функционал. Будь то класс, который точно не будет меняться или будет, но незначительно, либо api сервера, либо рендеринг компонентов на фронте. Первый смысл тестов показать себе и другим что функционал работает корректно и отвечает заданным критериям задачи. Второй смысл — гарантия что система не упадет при внесении изменений. И все. Если смысл написания какого то класса — поддержка функционала некой программы то тестировать отдельно сам класс смысла нет никакого, достаточно текста конечных точек программы. Если же класс предполагается использовать как универсальное решение в прочих проектах, то тесты для класса необходимы. И очень важный момент — тесты должны писаться ДО написания функционала, после написания функционала они будут просто тестировать сами себя на соответствие программе, а не программу на соответствие тестам.

На мой взгляд существует путаница в понятиях функциональный/приёмочный/юнит тест. Например в данной статье Владимир Янц как бы ставит знак равенства между функциональными и приёмочными тестами. В понимании фреймворка codeception — это разные виды тестов (https://codeception.com/docs/01-Introduction). Я считаю, разделение приёмочных и функцильнальных тестов полезно, поскольку начинаешь понимать, что между приёмочными и юнит-тестами существует разновидность тестов, не таких меддленных, как приёмочные, но при этом не таких чувствительных к изменениям архитектуры, как юнит-тесты. И вот такими «функциональными» (с точки зрения фреймворка codeception) тестами можно пользоваться с самого начала и не страдать при рефакторинге.
Привет! Спасибо за комментарий! Действительно я несколько упрощал и говорил о не-юнит-тестах как об одном целом. На самом деле действительно не все так просто и есть немало «оттенков серого». Кажется, на пирамиде тестирования можно однозначно положить только UI-тесты наверх, и Unit-тесты вниз, а вот в серединке есть разные варианты и вариаций там много. Но смысл один — чем выше по пирамиде тем больше частей приложения тестируется вместе и тем медленее/дороже/более хрупкими эти тесты становятся.
Например есть такой кейс:
есть набор классов, которые по раздельности, наверно, не особо имеет смысл тестить — они слишком маленькие.
возможно намельчили в разбиении и в понимании «единичной ответственности», но что есть то есть.
эти классы связываются через ди-конейнер, через него же туда прокидываются недостающие примитивы параметров — всякого рода костанты.
в итоге, этот микро-граф классов образует уже что-то пригодное для blackbox-тестирования, без вдавания в подробности реализации классов.
* получается, в тесте надо собирать эти классы вместе, для того чтобы начать их тестить, но если кто-то из разработчиков поменяет конфиг ди-контейнера, то тест станет неактуальным, хотя и продолжит отдавать зелёные результаты.
* другой вариант — доставать эти классики прямо из ди-контейнера в тесте, но тогда возникает вопрос — как замокать репозитории и прочие внешние зависимости в ди-контейнере, без постоянной пересборки его на каждый тест(медленно)

Не сталкивались с таким? Можете что-то посоветовать?

Думаю, что если для того чтобы протестить классы, их нужно доставать из контейнера, то я бы их не тестил как юниты. Скорее всего они все вместе выполняют какую-то верхнеуровневую задачу (конскольная команда, api ендпоинт, ещё что-то) — вот это бы и тестил.

В сборе они выполняют только часть верхнеуровневой задачи, это не целая ручка.
Как пример: цепочка прасеров чего либо.
Есть класс, который в конструктор получает регулярку. И таких классов N-штук. Классы одинаковые — регулярки разные.
Все эти классы списком заинжекчены в ChainOfResponsibility, который будет идти по списку до тех пор, пока мы не выпарсим что-то внятное.
Вся эта конструкция, и в том числе регулярки, описаны в контейнере.
Тестить классы сами по себе бессмысленно, нужно доставать из контейнера чейн и тестить его, причём вместе с конфигами, которые прокидываются через контейнер.

А бывают такие случаи, что там где-то графе зависимостей контейнера, зачесался еще и репозиторий, и в контейнере его уже не так просто замокать. Так как тесты должны быть независимыми друг от друга, то лучше контейнер потом пересобрать, что крайне долго.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий