====== Консольная утилита limb_unit ====== ===== Описание и установка ===== Для удобного выполнения тестов непосредственно из файловой системы можно использовать утилиту limb_unit, которая может быть установлена из пакета TESTS_RUNNER через [[http://pear.limb-project.com|Limb3 PEAR канал]]. Пример быстрой установки: $ pear channel-discover pear.limb-project.com $ pear install limb/tests_runner-alpha Эта утилита преобразует путь до файла или директории во внутреннее иерархическое представление тестов, что позволяет выполнять скрипты по инициализации/очищение фикстур и подклчюние настроек каскадно. Скрипту limb_unit необходимо передать путь до класса содержащего тест или директорию с группой тестов. Например: $ limb_unit my_test.php #подключение модуля с тестами и выполнение всех тестов модуля $ limb_unit MyTest.class.php #выполнение тестового класса MyTest $ limb_unit *_test.php #подключение всех модулей, подходящих под указанную *_test.php маску $ limb_unit tests #выполнение всех тестов из директории tests limb_unit может принимать следующие параметры: $ limb_unit [-c|--config= config.php] [-h] - путь файла или директории, поддерживаются метасимволы -c - позволяет подключить некоторый PHP файл, это удобно для назначения собственных настроек ===== Разделение тестовых файлов на классы и модули ===== Важно понимать, что в данный момент limb_unit различает файлы, содержащие тестовые классы по схеме **"один класс = один файл"**(такая схема используется повсеместно в Limb3) и просто PHP модули, которые могут содержать любое количество тестовых классов. Различие это важно по той причине, что SimpleTest имеет два базовых метода для подключения тестов: addTestCase($test) и addTestFile($file). Метод addTestCase подключает объект теста, а addTestFile подключает переданный файл через PHP конструкцию include и выбирает все подключенные тестовые классы. Проблема с методом addTestFile заключалась именно в использовании include - повторные подключения кода могут привести к ошибке "Cannot redeclare class XXX". Эта проблема была исправлена в SimpleTest путем добавления нового метода для подключения модулей - addTestFileOnce($file). Этот метод работает точно также как и addTestFile за тем исключением, что используется include_once вызов вместо include. limb_unit использует следующее соглашение для различия тестовых модулей и тестовых классов: * файлы с маской ** *_test.php, *.test.php ** являются тестовыми модулями * файлы с маской ** *Test.class.php ** - тестовые классы :!: Файлы, не попавшие ни под одну из масок, просто игнорируются. Тестовые модули подключаются в limb_unit с помощью addTestFileOnce, в случае же тестовых классов - через addTestCase(). Использование той или иной схемы хранения тестов(модули или "один класс = один файл") - дело вкуса разработчика, в принципе, ничто не мешает использовать эти подходы совместно. ===== Базовые примеры использования ===== Например, у нас есть следующая простая схема расположения тестов в файловой системе: a/a_test.php a/b_test.php a/b/c_test.php Каждый из файлов *_test.php представляет из себя модуль с одним или несколькими тестовыми прецедентами, например: //UnitTestCase подключается утилитой limb_unit из библиотеки SimpleTest автоматически class MyFooTest extends UnitTestCase { ... } class MyBarTest extends UnitTestCase { ... } Выполнение следующей команды из консоли: $ limb_unit a Приведет к тому, что будут выполнены тесты из файлов a_test.php, b_test.php, c_test.php. Выполним теперь такую команду: $ limb_unit a/b В результате будут выполнены тесты из файла c_test.php. Можно выполнять и тесты по отдельности для каждого файла, например: $ limb_unit a/a_test.php $ limb_unit a/b_test.php $ limb_unit a/b/c_test.php ===== Примеры использования фикстур и инициализационных файлов ===== Представим, что теперь у нас есть следующая схема расположения тестов в файловой системе: a/.setup.php a/.teardown.php a/.init.php a/a_test.php a/b_test.php a/b/.setup.php a/b/.teardown.php a/b/.init.php a/b/c_test.php a/b/d_test.php Выполним следующую команду в консоли: $ limb_unit a Это приведет к тому, что файлы будут подключены в таком порядке(из файлов *_test.php будут также выполнены тесты): - a/.init.php - a/.setup.php - a/a_test.php - a/b_test.php - a/b/.init.php - a/b/.setup.php - a/b/c_test.php - a/b/d_test.php - a/b/.teardown.php - a/.teardown.php Поясним, почему именно так: * Файл **.init.php**, помещенный в директорию, должен содержать некоторый общий инициализационный код(это обычный PHP файл), не связанный с фикстурами: подключение файлов, определение констант и проч. По этой причине эти файлы подключаются самыми первыми. Файлы инициализации являются опциональными. Пример подобной инициализации: **.init.php** * Пара файлов **.setup.php/.teardown.php** определяют фикстуру для конкретной директории: .setup.php - установка фикстуры, .teardown.php - ее удаление. .setup.php подключается до подключения тестов, .teardown.php, соответственно, после. Файлы фикстуры также обычные PHP скрипты. Однако есть небольшое замечание - эти файлы подключаются внутри объекта, поэтому можно передавать состояние фикстуры из .setup.php в .teardown.php, используя $this контекст. Файлы фикстур являются опциональными(например, можно иметь только .setup.php или .teardown.php). Пример фикстуры: **.setup.php** dump = new lmbTestDbDump(dirname(__FILE__) . '/.fixture/init_tests.sql'); ?> **.teardown.php** dump->clean(); ?> Теперь выполним такую команду: Выполним следующую команду в консоли: $ limb_unit b В результате будут подключены файлы в таком порядке: - a/.init.php - a/.setup.php - a/b/.init.php - a/b/.setup.php - a/b/c_test.php - a/b/d_test.php - a/b/.teardown.php - a/.teardown.php Как видно, фикстура и инициализационные файлы "наследуются" из вышестоящих директорий, т.е выполняются каскадно. Это же правило справедливо и при выполнении тестов для отдельных файлов. $ limb_unit b/c_test.php Это приведет к следующему подключению файлов: - a/.init.php - a/.setup.php - a/b/.init.php - a/b/.setup.php - a/b/c_test.php - a/b/.teardown.php - a/.teardown.php ===== Примеры управления выполнения тестов ===== На данный момент утилита limb_unit предоставляет только одно средство контроля выполнения тестов - игнорирование выполнения тестов в директории по некоторому условию. Это бывает полезно, когда необходимо пропустить тесты, которые требуют особых условий среды, например, наличие PHP модуля, библиотеки, соединения с БД и проч. Для контроля выполнения тестов в директории следует создать скрипт **.ignore.php** в этой директории. Используя конструкцию **return**, скрипт обязан вернуть true или false, соответственно, если необходимо пропустить или продолжить выполнение тестов в директории. Пример подобного скрипта: **.ignore.php** getDefaultDbConnection()->getType() != 'mysql'; ?> Данный скрипт пропустит выполнение тестов в директории, если текущее подключение к БД не типа 'mysql'. ===== Пример кастомизации limb_unit ===== Зачастую бывает так, что для выполнения тестов в приложении требуются некоторые дополнительные настройки. Например, для выполнения тестов на пакеты Limb3 необходимо выставить значение константы LIMB_VAR_DIR(директория с временными файлами) или параметры доступа к тестовой БД и проч. limb_unit имеет базовые средства для подключения настроечных скриптов, которые, по сути, являются обычными PHP файлами. Для подключения настроечных скриптов используется опция **-c** или ее длинный аналог **--config=**, например: $ limb_unit -c my_settings.php ... Скрипт my_settings.php(а следовательно и настройки), будет подключен до подключения кода тестов. Пример подобных настроек может быть таким: Естественно, каждый раз набирать длинную команду "limb_unit -c my_settings.php ..." занятие довольно утомительное, поэтому рекомендуется сделать короткий алиас на эту команду или средствами shell или, как, например, в Windows, создав .bat скрипт и поместив его в директорию, включенную в Path. Например: **unit.bat** @echo off limb_unit -c /home/bob/dev/tests/setup.php %* Теперь в консоли тесты можно удобным образом запускать так: $ unit foo_test.php Можно пойти чуть дальше и сделать еще более кастомизированную версию limb_unit. Дело в том, что порой необходимо протестировать код под разными версиями PHP, с дебаггером и проч. Каждый раз править php.ini занятие крайне скучное, поэтому можно сделать следующее - запускать limb_unit в обход скрипта, поставляемого вместе с PEAR, напрямую подключая код пакета TESTS_RUNNER. Для этого всего лишь требуется отдать на исполнение PHP интерпретатору скрипт bin/limb_unit.php из пакета TESTS_RUNNER. Например: **unit.bat** @echo off php d:/var/dev/limb/3.x/limb/tests_runner/bin/limb_unit.php -c d:/var/dev/limb/3.x/tests/setup.php %* Здесь уже разработчик не ограничен использовать ту или иную версию PHP, можно сделать даже несколько версий подобных скриптов под разные версии PHP, с разными настройками и проч. Например: **unitv.bat** @echo off %1 d:/var/dev/limb/3.x/limb/tests_runner/bin/limb_unit.php -c d:/var/dev/limb/3.x/tests/setup.php %2 %3 %4 %5 %6 Использование: $ unitv php552 my_test.php $ unitv php551 my_test.php $ unitv php-debug my_test.php ===== Законченный пример кастомизации limb_unit ===== Для полной картины здесь приводится пример кастомизации limb_unit в том виде, как это практикуется у Limb3 разработчиков. * Создаем отдельную директорию, которая будет из себя представлять тестовый проект для всех тестов, выполняемых при помощи limb_unit, например /home/bob/dev/tests * Создаем в ней скрипт setup.php примерно такого содержания: * Т.к мы добавили директорию /home/bob/dev/tests в include_path, то теперь поиск настроек будет происходить и в этой директории. Это важно для WEB_APP пакета, который берет настройки для подключения из конфигурационного файла **db.conf.php**. Создадим этот файл в директории /home/bob/dev/tests/settings: LIMB_DB_DSN);//используем константу из setup.php ?> * Также на время тестирования имеет смысл настроить WACT таким образом, чтобы он не производил кеширование компилированных шаблонов и путей до шаблонов. Чтобы изменить это поведение создадим файл /home/bob/dev/tests/settings/wact.conf.php: 1, 'forcecompile' => 1); ?> * Теперь для удобства запуска тестов создадим алиас на limb_unit, например, назовем его unit: #!/bin/sh limb_unit -c /home/bob/dev/tests/setup.php "$@" * Для продукционной среды мы настоятельно рекомендуем *nix операционные системы, однако во время разработки зачастую приходится работать под Windows поэтому здесь приводится пример схожего bat скрипта: @echo off limb_unit -c c:/var/dev/tests/setup.php %*