Сегодня я хочу поделиться подходом, который сделал работу над сложными PHP проектами проще, который дал мне больше свободы в написании моих программ, который спасает мои нервные клетки и делает жизнь веселее. Этот подход называется TDD, а говоря простым языком — разработка через тестирование. Об этом сказано немало, много копий было сломано в спорах, но тем не менее в среде php-разработчиков это до сих пор не стало частью процесса разработки. Я думаю основной причиной этого является специфика веб-приложений, ориентированных на интерфейсы, итеративная разработка по сценарию «пишу-смотрю-пишу-смотрю». Отдельная история это то что львиная доля разработчиков это «вебмастера», зачастую знающие о программировании «PHP за 24 часа», либо студенты с опытом написания лабораторных работ на С (эта категория настолько сурова, что даже книг не читает, именно им мы обязаны тысячам изобретенных велосипедов). С другой стороны, подкупаемые простотой написания приложений для веб и огромным спросом на них в PHP, в разработку подтянулись разработчики с опытом в Java, С, Delphi начав продвигать TDD (там юнит-тесты стали давно неотъемлемой практикой разработки). Так в чем же дело? Почему преимущества написания тестов на код не очевидны на столько, что бы все разработчики начали использовать их? Думаю всё дело в опыте. Именно с опытом приходит понимание преимуществ, которые дают ОПП, паттерны, а вместе с этим и использование TDD. Действительно, традиционный винегрет из HTML и PHP с трудом поддается тестированию и, как правило, попытки привести в порядок такой код выглядит больше не как рефакторинг, а как переписывание.
Мой путь к тестам лежал в первую очередь через осознание того что мой код хрупок. Это не так просто, как может показаться на первый взгляд, — дело в том что в программистах очень живуч миф о «совершенности» их кода. Действительно, каждый раз когда в коде находится баг, программист в первую очередь думает о том где ошибся тестировщик, а уж потом, ищет проблему в программе. Если же в вас живет скептик, критикующий производимый вами код, у вас появляется сильное желание «успокоить его», подписав логгирование, обработчики ошибок и постоянно тестируя всё что пишите. В какой-то момент, когда бизнес начинает требовать от вас радикального поворота в логике вашего приложения, и вы понимаете что для поддержания целостности приложения и уверенности в том что оно всё еще работает «как надо», вам нужно проделать такой же объём работы, который вы уже проделали, и вы понимаете — будь у вас под рукой что-то типа тестов, это спасло бы ваши выходные. То есть понимание необходимости в модульных тестах приходит именно через сложности в разработке больших и сложных приложений. Я не напрасно написал «больших и сложных», — именно так. Для простых это может показаться лишним, так как если у вас нет большого опыта работы с тестами, вы будите писать медленнее, но если опыт есть, то и для небольших проектов модульные тесты это хорошая практика, так как «большие и сложные» проекты часто вырастают из небольших, и поэтому если ваш небольшой проект спроектирован должным образом и покрыт тестами это будет отличной площадкой для развития проекта и наращивания функциональности. Если же проект большой и несложный, для веб-приложений, это как правило, большое количество пользовательских форм, простая логика сохранения и отображения информации модульное тестирование также не будет «спасательным кругом», безусловно, тесты на основные классы должны быть написаны, но главной составляющей качества вашего продукта будет скорее всего функциональное тестирование интерфейсов. А вот в случае «больших и сложных» проектов тесты, неотъемлемая составляющая проекта. В противном случае «вертолет» может «не взлететь».
Итак, вы стоите на пороге нового проекта, понимание важности тестов у вас есть, и вы хотите знать, как «сделать правильно». Теперь самое время уделить вашему пониманию ООП, и умению использовать паттерны проектирования. Для того чтобы систему было легко тестировать, легко изменять функциональность, без постоянного переписывания тестов систему нужно проектировать хорошо. Если у вас в команде есть архитектор или разработчик с большим опытом, то вам крупно повезло — на множество «граблей», присущих новичкам, вы не наступите. То есть «грабли» конечно же будут, но это будут уже более «высокоуровневые» просчеты в архитектуре, а не глупые ошибки. Вы будете постигать нюансы построения бизнес логики для более простого тестирования, будете открывать секреты построения красивых интерфейсов для своих классов, предоставляя максимум свободы внутри классов и позволяя кардинально менять логику классов без переписывания тестов. Вы будете учиться оптимизировать тесты и вплетать их в ваш процесс разработки и на этом пути никогда не будет скучно или неинтересно. Модульное тестирование это увлекательный процесс и я гарантирую что если вы пойдете по нему, он отблагодарит вас новым уровнем качества вашего кода и ваших приложений. Пробуйте, интегрируйте запуск тестов в свою IDE и расскажите мне о ваших успехах.