Инструменты пользователя

Инструменты сайта


limb3_2007_2:ru:packages:tests_runner:limb_unit

Консольная утилита limb_unit

Описание и установка

Для удобного выполнения тестов непосредственно из файловой системы можно использовать утилиту limb_unit, которая может быть установлена из пакета TESTS_RUNNER через 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] <file_path>
<file_path> - путь файла или директории, поддерживаются метасимволы  
-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 будут также выполнены тесты):

  1. a/.init.php
  2. a/.setup.php
  3. a/a_test.php
  4. a/b_test.php
  5. a/b/.init.php
  6. a/b/.setup.php
  7. a/b/c_test.php
  8. a/b/d_test.php
  9. a/b/.teardown.php
  10. a/.teardown.php

Поясним, почему именно так:

  • Файл .init.php, помещенный в директорию, должен содержать некоторый общий инициализационный код(это обычный PHP файл), не связанный с фикстурами: подключение файлов, определение констант и проч. По этой причине эти файлы подключаются самыми первыми. Файлы инициализации являются опциональными. Пример подобной инициализации:

.init.php

<?php
require_once(dirname(__FILE__) . '/../../common.inc.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

<?php
require_once('limb/dbal/src/lmbTestDbDump.class.php');
$this->dump = new lmbTestDbDump(dirname(__FILE__) . '/.fixture/init_tests.sql');
?>

.teardown.php

<?php
$this->dump->clean();
?>

Теперь выполним такую команду:

Выполним следующую команду в консоли:

$ limb_unit b

В результате будут подключены файлы в таком порядке:

  1. a/.init.php
  2. a/.setup.php
  3. a/b/.init.php
  4. a/b/.setup.php
  5. a/b/c_test.php
  6. a/b/d_test.php
  7. a/b/.teardown.php
  8. a/.teardown.php

Как видно, фикстура и инициализационные файлы «наследуются» из вышестоящих директорий, т.е выполняются каскадно. Это же правило справедливо и при выполнении тестов для отдельных файлов.

$ limb_unit b/c_test.php

Это приведет к следующему подключению файлов:

  1. a/.init.php
  2. a/.setup.php
  3. a/b/.init.php
  4. a/b/.setup.php
  5. a/b/c_test.php
  6. a/b/.teardown.php
  7. a/.teardown.php

Примеры управления выполнения тестов

На данный момент утилита limb_unit предоставляет только одно средство контроля выполнения тестов - игнорирование выполнения тестов в директории по некоторому условию. Это бывает полезно, когда необходимо пропустить тесты, которые требуют особых условий среды, например, наличие PHP модуля, библиотеки, соединения с БД и проч.

Для контроля выполнения тестов в директории следует создать скрипт .ignore.php в этой директории. Используя конструкцию return, скрипт обязан вернуть true или false, соответственно, если необходимо пропустить или продолжить выполнение тестов в директории.

Пример подобного скрипта:

.ignore.php

<?php
return lmbToolkit :: instance()->getDefaultDbConnection()->getType() != 'mysql';
?>

Данный скрипт пропустит выполнение тестов в директории, если текущее подключение к БД не типа 'mysql'.

Пример кастомизации limb_unit

Зачастую бывает так, что для выполнения тестов в приложении требуются некоторые дополнительные настройки. Например, для выполнения тестов на пакеты Limb3 необходимо выставить значение константы LIMB_VAR_DIR(директория с временными файлами) или параметры доступа к тестовой БД и проч. limb_unit имеет базовые средства для подключения настроечных скриптов, которые, по сути, являются обычными PHP файлами.

Для подключения настроечных скриптов используется опция -c или ее длинный аналог –config=, например:

$ limb_unit -c my_settings.php ...

Скрипт my_settings.php(а следовательно и настройки), будет подключен до подключения кода тестов. Пример подобных настроек может быть таким:

<?php
//используем cvs версию SIMPLE_TEST вместо встроенной в TESTS_RUNNER
@define('SIMPLE_TEST', '/home/bob/dev/external/simpletest-cvs/'); 
//запрещаем кеширование метаданных БД
@define('LIMB_CACHE_DB_META_IN_FILE', false); 
//объявляем путь до временной директории
@define('LIMB_VAR_DIR', '/home/bob/dev/var/'); 
?>

Естественно, каждый раз набирать длинную команду «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 примерно такого содержания:
<?php
//во-первых добавляем директорию /home/bob/dev/tests в include_path
//во-вторых добавляем директорию с Limb3 в include_path
set_include_path(dirname(__FILE__) . '/' . PATH_SEPARATOR . 
                 '/home/bob/dev/limb/3.x/' . PATH_SEPARATOR);
 
//запрещаем кеширование метаданных БД
@define('LIMB_CACHE_DB_META_IN_FILE', false);
//директория с временными файлами будет расположена в /home/bob/dev/tests/var
@define('LIMB_VAR_DIR', dirname(__FILE__) . '/var/');
//устанавливаем параметры доступа к БД
@define('LIMB_DB_DSN', 'mysql://root:secret@localhost/all_tests?charset=utf8');
?>
  • Т.к мы добавили директорию /home/bob/dev/tests в include_path, то теперь поиск настроек будет происходить и в этой директории. Это важно для WEB_APP пакета, который берет настройки для подключения из конфигурационного файла db.conf.php. Создадим этот файл в директории /home/bob/dev/tests/settings:
<?php
$conf = array('dsn' => LIMB_DB_DSN);//используем константу из setup.php
?>
  • Также на время тестирования имеет смысл настроить WACT таким образом, чтобы он не производил кеширование компилированных шаблонов и путей до шаблонов. Чтобы изменить это поведение создадим файл /home/bob/dev/tests/settings/wact.conf.php:
<?php
$conf = array('forcescan' => 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 %*

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
   ____  ____    ___    ___    ___ 
  / __/ / __ \  / _ \  / _ \  / _ \
 _\ \  / /_/ / / , _/ / ___/ / ___/
/___/  \____/ /_/|_| /_/    /_/
 
limb3_2007_2/ru/packages/tests_runner/limb_unit.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)