Итак, вы хотите писать тесты

Меня часто просят дать несколько советов о том, с чего начинать написание тестов для PHP. Вы обратились по адресу, так как я представляю себя в качестве эксперта-ниндзя-рок-звезды-сенсея-самоуверенного-эгоиста по этой теме. Я долго боролся с придумыванием ответа, который должен поместиться в 140 символов Twitter-сообщения. И вот недавно мне стало очевидно, что данная тактика не принесет плодов. Излагаю свои мысли о том, как начать работу с тестированием PHP-кода.

Научиться распознавать непроверяемый код

Худшее в мире чувство программист испытывает тогда, когда, сидя за монитором, видит перед собой кусок кода, который писал кто-то другой, а этот код имеет решающее значение для успеха проекта. Многие не удержатся и заметят: если не дай бог ты здесь что-нибудь сломаешь, случится полный крах.

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

Когда дело доходит до тестирования кода, существуют два принципа, к выполнению которых вы должны стремиться:

  • найти способ передать зависимости в коде;
  • найти способ сломать код в наименьше возможном модуле.

Следуя этим двум простым, но чрезвычайно трудно реализуемым идеям, вы получите в конечном итоге код, для которого писать тесты становится простейшей задачей, тогда вы будете проводить тестирование, не задумываясь.

Откажитесь от вызовов статических методов. Избавьтесь от этих частных и защищенных методов. Остановите создание новых объектов внутри метода. Подумайте о передаче данных, а не объектов. Убедитесь, что ваши методы имеют мало или не имеют вообще побочных эффектов. Отделите ваш источник данных от кода, который манипулирует его результатами. Что еще более важно, разберитесь в том, почему все эти вещи являются препятствиями на пути к легко проверяемому коду.

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

Продолжайте изучать язык

Тесты представляют собой обычный код. Вывод — продолжайте учиться лучше писать PHP-код. Многое на PHP Sadness может помочь нам в этом. Обязательно изучите iterator drinking game.

В общем, чем больше вы знаете о языке, тем больше вероятность того, что вы узнаете, как решать задачи базовой функциональности вместо постоянного внедрения в код решений, которые Вы написали сами.

Объединение юнитов кода

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

Если вы когда-либо искали в сети способы сделать что-то из командной строки в различных версиях Linux-дистрибутивов, вы поймете, что я имею в виду. “Take sed and cat and awk and grep and pipe it through cut and then to sort and you will get exactly what you want.”

Такого рода вещи прекрасно вписываются в концепцию написания небольших модулей легко проверяемого кода.

Начните задавать вопрос «Как я собираюсь проверить это?»

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

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

Я не говорю что, у каждой проблемы есть тестируемое решение. Но любая проблема, где ожидаемые результаты, основываются на известных начальных данных, — это сценарий, который можно протестировать. Запросы к базе данных, Сторонние API, Маршрутизация запросов, Fizz Buzz — все эти вещи мы можем проверить.

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

Добавление новых возможностей превращается в совершенно простой процесс, включающий в себя:

  • разработку новых функций;
  • написание тестов для этих новых функций;
  • написание код, во время тестирования;
  • своевременный уход домой.

 

Не используйте код без доказательств его исправности

Конечно, у вас нет никаких тестов ПРЯМО СЕЙЧАС. Но я уверен, что у вас есть ошибки в коде, которые можно исправить. Напишите тесты, чтобы убедиться, что ошибка существует. Я уверен, что вы найдете ваш код никак не модульным или проверяемым, как вы думали раньше.

После того как вы увидели ошибку, работайте над кодом до ее устранения. Затем используйте обновленный код в разработке. Повторяйте операции, пока не получите высокоориентированный набор тестов. Это то, что я называю Тестированием в реальных условиях.

Итак, убедитесь, что ничего, из того что не проверено, не используется в разработке.

Нет ручной работе

Это 2-й год 2-го десятилетия 21-го века. В интернете полно инструкций о том, как автоматизировать все, что угодно.

Chef. Puppet. Shell-скрипты. Jenkins. Travis. Виртуальные серверы. Изучите эти вещи. Используйте их, и вы будете благодарить меня. Отправьте мне деньги через PayPal — этого будет достаточно. Автоматизируйте все, что вы делаете вручную, а затем выясните, есть ли способы автоматизировать и автоматизацию. Вы можете быть удивлены.

Прекратите использовать инструменты без тестов

Я отношусь к любому PHP-инструменту, который не имеет собственного набора тестов, как к черному ящику — с некоторым недоверием. Черный ящик — не та вещь, на которую можно положиться, когда ситуация выходит из-под контроля. Любой код, который вы не можете легко проверить, надо считать подозрительным и опасным. Я чувствую то же самое даже по отношению к коду, который сам написал, так что представьте, что я должен думать о вещах написанных другими людьми.

Всегда перепроверяйте, если все правильно

Интеграционные тесты — обман. Юнит-тесты не исправляют ошибки. Достаточно простой код не требует испытаний. Парное программирование — обременительная практика. PHP — отстой. Мобильные приложения — будущее. Документация — после сделанной работы. Никто не любит разработчика, который задает слишком много вопросов. Вы работаете в реальном мире, где результат имеет значение. Асинхронные вызовы всегда приводят к плохим последствиям.

Не все вышеперечисленное справедливо. Единственный способ узнать для себя — правда это или ложь — испытать на собственном опыте.