CTO Vetmanager, PHP Developer, Ironman 70.3

Еще раз про тестирование

TDD - это холиварная тема, особенно когда речь идет о 100% покрытии кода тестами. Определенно, тесты помогают писать хороший код и использовать с умом их просто необходимо.

Процитирую Сергея Капралова с телеграмм канала #painofoop

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

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

Unit Test - тестирование поведение функций и классов.

Я пишу функцию факториал и на неё пишу юнит тесты

factorial(1) == 1;
factorial(0) == 1;

Вы пишите функцию, результат которой зависит только от аргументов? Идеальный случай. Создайте юнит тест. Тестирование таких функций дает максимальный профит и удовольствие.

Я пишу класс парсер строки и делаю юнит тест

(new DateParser("Тут где-то дата 15.02.86"))->date() == "15.02.86";

Вы пишите класс, публичные методы которого возвращают результат и он зависит только от состояния свойств объекта? Супер! Это наш случай, пишите юнит тесты.

Я пишу обработчик json полученный с какого-то сервера.

Класс, который зависит только от состояния свойств, делаю юнит. Тот же случай как и парсер даты.

expectException(\Exception::class)
(new SomeSericeResponse('{success: false}'))->userId();

На таких тестах вы получите опыт и понимание ценности тестов. Старайтесь писать больше такого кода, это можно делать и за счет завязки на абстракцию, а не на реализацию. Вместо того чтобы дергать $_SESSION['clinic_id'] и завязываться на компоненты, мы можем передать это в конструктор или аргументы метода. Или использовать абстракцию сессии.

Интеграционные(Integration) - тестирование работы компонентов в связке.

Конечно, невозможно все проверить при помощи юнит тестов. Нам нужно проверить создался ли файл в с3? Отправился ли апи запрос на сервер. Мы пишем интеграционный тест, таких тестов не должно быть много. Они не должны проверять математику или какую-то логику класса, а только сам факт запроса, факт того что компоненты взаимодействуют верно. Математика должна быть в чистых функциях и классах и тестироваться юнит тестами.

Такие тесты тяжело запускать локально, они работают дольше, их запуск тяжело настроить в CI, они хрупкие ибо могут зависеть от внешних факторов.

Такими тестами проще мыслить, под них проще писать код, архитектура не нужна.

Пусть у вас будет их меньше чем unit.