Технология экстремального программирования предполагает наличие определенных стартовых условий. Например, вы должны быть готовы с самого начала проектирования внедрить в ваш проект избыточный код. Причем по мере увеличения функциональности задачи этот код также должен разрастаться в объемах. Основное его назначение — проверка работоспособности ваших классов и функций, а также тестирование входных и выходных данных для приложения. В моей первой статье («Функции тестирования в PHP-проектах») про применение технологий ударного проектирования (или экстремального программирования, как называют его большинство разработчиков) был сделан упор на концепцию введения таких методов проектирования в уже готовый проект.
В сегодняшнем материале я хотел бы сделать упор на применение готового программного обеспечения, которое создано специально для внедрения таких технологий в готовые и проектируемые системы. Итак, сегодняшняя статья прольет немного света на SimpleTest.
С чего начать использование, или Несколько слов про идеологию
В отличие от простейшего подхода к организации тестирования путем самостоятельного написания методов проверки классы SimpleTest позволяют кардинально расширить возможности тестируемого кода. Идеологически само тестирование бета-кода происходит в обертке класса, который наследует возможности базового объекта SimpleTest. Этот базовый класс позволяет выполнять массу стандартных действий вроде проверки значения переменной на True или False и выдачи сообщений. Таким образом, если вы решились на введение профессионального подхода к решению проблемы автоматического тестирования в вашем веб-приложении, следует быть готовым к довольно частому применению объектного кода и переносу части вашей функциональности в PHP-классы. Итак, с чего же начать сам процесс перевода вашей задачи на рельсы экстремального программирования? Вначале на все том же SourceForge скачиваем программные модули для тестирования. Следует отметить, что программный продукт хоть и совершенно работоспособен, но находится в стадии альфа-тестирования, что должно откладывать некий отпечаток на весь процесс вашего ознакомления с ним (например, надо быть готовым отправить отчет про найденную вами ошибку его разработчикам). Далее размещаем содержимое архива в подкаталоге simpletest вашего веб-приложения. После этого следует определиться с перечнем функций вашей задачи, которые необходимо в первоочередном порядке подвергнуть тестированию. Их можно отобрать как по критерию частоты использования, так и по другим критичным именно для вашего приложения параметрам. Например, можно отобрать для начала наиболее длительные по времени исполнения или наиболее часто корректируемые функции.
Следует заметить, что в плане удобства для самого разработчика к задаче тестирования любого веб-приложения можно применить два подхода. Можно встроить код тестирования в саму задачу и тем самым перенести часть ответственности за тестирование приложения на плечи пользователей (мало ли какая ошибка вылезет в процессе использования ваших скриптов) либо изначально разделить местоположение тестируемого кода и основного веб-приложения. В любом случае отличной идеей будет включение функциональности тестирующего кода в итоговое веб-приложение хотя бы в качестве дополнительной информационной службы для команды разработчиков. Поэтому, наверное, самым подходящим местоположением для функций SimpleTest будет одноименный подкаталог вашего веб-приложения. Разместив скрипты таким образом, вы получаете возможность проверять код, уже находящийся на стороне сервера, что достаточно удобно как в плане поддержки веб-приложения, так и в плане защищенности самого заказчика от посягательств на его безопасность.
Для демонстрации процесса попробуем вынести в обязательно тестируемые функции часть класса, предназначенного для выдачи сообщений пользователям и ведения текстового лога. Для простоты изложения ограничусь самой простой функциональностью такого класса. Предположим, он будет создавать текстовый лог при вызове из пользовательского скрипта. На приведенном ниже снимке экрана приведен упрощенный код такого класса, который, однако, способен дать представление про процесс тестирования.
Как выглядит тестирующий код
Итак, каким образом выглядит подключение классов SimpleTest к вашему приложению? В первую очередь необходимо физически связать вашу задачу и тестирующие функции. Для этого следует включить в тестирующий код сами классы (как минимум файлы simpletest/unit_tester.php и simpletest/reporter.php) SimpleTest с помощью директив require_once. Сам тестирующий код по замыслу разработчиков должен выделяться в отдельный класс, который наследует свойства родительского объекта. Этим объектом является класс UnitTestCase, который содержит функции, необходимые для проверки разнообразных значений, которые могут возвращать методы ваших классов.
Наиболее простыми методами этого класса являются методы assertFalse и assertTrue, которые позволяют проверить функции, возвращающие логические значения True или False. Таким образом, проверка может осуществляться путем вызова одного из методов, в качестве параметра которого передается тестируемая функция с необходимым для нее набором параметров. Точнее говоря, тест-функции будет передаваться результат выполнения метода вашего класса. На следующем листинге вы можете увидеть пример вызова таких методов для класса PHP-логгера.
Здесь следует дать некоторое пояснение по коду. Первый вызов функции assertFalse используется для проверки отсутствия лог-файла непосредственно после инициализации класса. Таким образом, предполагается, что ваш лог-класс создает текстовый лог не из своего конструктора (метод PHP-класса с именем, которое соответствует имени класса), а лишь во время вывода сообщений. Тестовый пример написан некорректно в этом плане, поскольку лог-файл создается во время инициализации класса. Таким образом, вызов этого метода применительно к существующему лог-классу должен выдать ошибку. Следующий вызов тестирующего метода assertTrue проверяет наличие текстового лог-файла после вывода сообщения в лог-файл. В результате запуска этого тестового скрипта вы получите отчет (указывающий на некорректную работу класса), приведенный на следующем рисунке.
Приведенный снимок экрана показывает часть рабочего пространства среды быстрой разработки Eclipse, которая позволяет проводить быструю разработку и тестирование PHP-кода. Однако вы можете использовать SimpleTest и совершенно отдельно от этой среды разработки.
Другие методы
Кроме простейших методов для проверки логических значений SimpleTest имеет массу других тестовых функций. Вот список тестовых функций, которые можно использовать в текущей версии SimpleTest:
- assertTrue($x) — выдается ошибка, если значение False;
- assertFalse($x) — получаете ошибку тестирования, если переданное значение True;
- assertNull($x) — проверка, существует ли переданное значение;
- assertNotNull($x) — указанное в параметрах метода значение не должно существовать;
- assertIsA($x, $t) — переменная $x не должна иметь тип $t;
- assertNotA($x, $t) — проверка на соответствие типа переменной $x строке $t;
- assertEqual($x, $y) — проверка на равенство $x и $y;
- assertNotEqual($x, $y) — проверка на неравенство $x и $y;
- assertWithinMargin($x, $y, $m) — проверка того, что разница $x и $y меньше $m;
- assertOutsideMargin($x, $y, $m) — разница $x и $y больше $m;
- assertIdentical($x, $y) — проверка полной идентичности (одновременно типа и значения переменных);
- assertNotIdentical($x, $y) — проверка неидентичности значений;
- assertReference($x, $y) — ошибка выдается, если $y не является ссылкой на переменную $x;
- assertCopy($x, $y) — в случае если $y — ссылка на $x, выдается ошибка;
- assertPattern($p, $x) — проверка строки $x по регулярному выражению $p;
- assertNoPattern($p, $x) — несоответствие строки $x регулярному выражению $p;
- assertNoErrors() — при выполнении кода не было ошибок;
- assertError($x) — в коде должна быть ошибка.
Вспомогательные методы SimpleTest
Для передачи сообщений в итоговый отчет и автоматизации некоторых функций, а также для тестирования собственной работоспособности SimpleTest предлагает набор специальных вспомогательных методов. Метод setUp (setDown) позволяет указать функцию, которая будет выполняться перед (после) каждым вызовом тестового метода класса. Функции pass() и fail() вызываются в качестве теста для самих классов SimpleTest. Метод sendMessage() передает пользовательское сообщение в итоговый отчет. Для очистки очереди ошибок можно применить метод swallowErrors.
Группировка тестовых скриптов
Для упрощения запуска множества тестовых скриптов (предполагается, что каждый ваш класс будет иметь тестовый скрипт) SimpleTest предлагает специальный класс GroupTest, который умеет вызывать набор тестов. Фактически необходимо создать набор тестовых скриптов и прописать их вызовы в отдельном (можно назвать его главным) тестовом скрипте. Таким образом, вы получите возможность автоматического тестирования всех функций вашего приложения одним махом.
Применение
Использование SimpleTest в качестве тестирующего класса для вашего веб-приложения позволит добавить не только стабильности его работе. Вы можете быть уверены в правильности написанного кода в любой момент разработки, когда над одним и тем же классом работают несколько программистов. В функциональности SimpleTest есть множество других возможностей, которые позволяют протестировать ваше приложение. В этой статье приведены самые простые примеры, которые, однако, дают возможность ввести процедуру тестирования в ваше приложение. В случае если вы используете Eclipse, можно также использовать специальное расширение, которое позволит упростить процесс запуска тестирующего кода. В самом же простейшем случае есть смысл использовать простейшую гиперссылку с всплывающим окном, которое будет показывать результаты тестирования функций в текущем коде.
В заключение
Процесс тестирования несет в себе несколько негативных моментов, таких как затягивание разработки проекта, необходимость изучения новых возможностей тестирующих классов. Для введения функционального тестирования вам придется написать немало дополнительных функций. Некоторые из них могут оказаться сложнее самих «подопытных» методов. Следует, конечно, помнить, что с точки зрения большинства заказчиков такие тестирующие процедуры — бессмысленная трата их средств и времени. Однако не стоит забывать и о том, что надежность вашего кода и его качество многократно возрастут. Поэтому даже в случае наличия жестких временных ограничений по ходу выполнения проектов стоит использовать процедуры тестирования в самых узких и сложных местах вашего приложения.
Ссылки по теме
- Экстремальное программирование по-русски
- SimpleTest для PHP
- Платформа для быстрой разработки Eclipse
Статья получена: hostinfo.ru