Установка ZendOptimizer на php5.3 в Debian
Добавляем в репозитории deb http://repos.zend.com/zend-server/deb server non-free wget http://repos.zend.com/zend.key -O- | apt-key add -
apt-get update
Далее смотрим поиском apt-cache search zend
Устанавливаем apt-get install zend-server-ce-php-5.3
Ожидаем немного
Zend Framework, PHPUnit, модульное тестирование
Идея модульного тестирования состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода чтобы потом быстро проверять, не привело ли очередное изменение кода к появлению ошибок в уже проверенных местах программы.
Что легче - писать юнит-тесты или сто раз проверять всю программу вручную - каждый решает сам, но для этого нужно попробовать оба способа и сравнить.
В Zend Framework для этого уже все подготовлено (ну почти). Речь пойдет о версии ZF 1.11.11, которая сейчас считается последней stable.
При создании проекта, рядом с каталогом application создается каталог tests, в котором файлы phpunit.xml, bootstrap.php и application/controllers/IndexControllerTest.php Контроллер в последнм файле наследует класс Zend_Test_PHPUnit_ControllerTestCase, который создает нам основу для написания тестов для инструмента PHPUnit.
PHPUnit можно установить через pear в консоли:
pear channel-update pear.php.net pear upgrade pear pear channel-discover pear.phpunit.de pear channel-discover components.ez.no pear channel-discover pear.symfony-project.com pear install phpunit/PHPUnit
После этого, набрав в консоли phpunit для первого ее запуска, я увидел следующий привет:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/curl.so' - /usr/lib/php5/20090626+lfs/curl.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/gd.so' - /usr/lib/php5/20090626+lfs/gd.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/mcrypt.so' - /usr/lib/php5/20090626+lfs/mcrypt.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/mysql.so' - /usr/lib/php5/20090626+lfs/mysql.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/mysqli.so' - /usr/lib/php5/20090626+lfs/mysqli.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/pdo_mysql.so' - /usr/lib/php5/20090626+lfs/pdo_mysql.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/pdo_sqlite.so' - /usr/lib/php5/20090626+lfs/pdo_sqlite.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/sqlite.so' - /usr/lib/php5/20090626+lfs/sqlite.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/sqlite3.so' - /usr/lib/php5/20090626+lfs/sqlite3.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/xsl.so' - /usr/lib/php5/20090626+lfs/xsl.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHPUnit 3.6.7 by Sebastian Bergmann.
Судя по ошибкам, Приложение ищет библиотеки тут /usr/lib/php5/20090626+lfs/ А на моем Zend Server они тут: /usr/local/zend/lib/php_extensions/
Проще всего сделать ссылки на них там где их ищут: [code]$ ln /usr/local/zend/lib/php_extensions/* /usr/lib/php5/20090626+lfs/
Ошибок стало меньше, осталось только 2: [code]PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/pdo_sqlite.so' - /usr/lib/php5/20090626+lfs/pdo_sqlite.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/sqlite3.so' - /usr/lib/php5/20090626+lfs/sqlite3.so: cannot open shared object file: No such file or directory in Unknown on line 0 PHPUnit 3.6.7 by Sebastian Bergmann.
Все равно не аккуратненько получается :)
Посмотрел вывод phpinfo через консоль, оказалось что проблема при каждом запуске php из консоли (а не только для этой проги), а потому что php.ini совсем другой, не зендовский а /etc/php5/cli/php.ini
Но при смене в нем include_path - еще больше проблем, поэтому залез в /etc/php5/cli/conf.d и в ini файлах sqlite3 и pdo_sqlite закомментировал расширения (точка с запятой впереди). - Ошибок больше нет.
Для запуска теста заходим в консоли в каталог tests и пишем phpunit:
# phpunit [code]PHPUnit 3.6.7 by Sebastian Bergmann. Configuration read from /var/www/sysadmin-komi.ru/tests/phpunit.xml Time: 1 second, Memory: 7.50Mb OK (1 test, 1 assertion)
Все ок. Можно писать свои тесты в контроллере, который создан при создании проекта.
В тестах можно создавать любые объекты моделей и выполнять запросы к сайту.
Например, я попробовал пройтись по 200 страницам сайта с несколькими проверками:
public function testTestAction()
{ for ($i = 1; $i < 200; $i++)
{ // Запускаем страницы в диапазоне цикла $this->dispatch('/page' . $i);
# http://localhost/page1 , http://localhost/page2 ...
// $this->getRequest()->getParam('page') всегда получает номер правильно
// (в данном диапазоне это так и будет) $this->assertEquals($this->getRequest()->getParam('page'), $i);
// проверяем как справляется маршрутизация $this->assertModule('default');
$this->assertController('index');
$this->assertAction('index');
// в контенте есть тэг с аттрибутом id=content
$this->assertTag(array('id' => 'content'), $this->getResponse()->getBody());
// перезапускаем все, чтобы вернуть в исходное состояние
this->setUp();
} }
Можно также использовать другие методы phpunit, вот небольшой списочек из статьи с хабра http://habrahabr.ru/blogs/php/56289/ :
assertTrue() / assertFalse() assertEquals() / assertNotEquals() assertGreaterThan() assertGreaterThanOrEqual() assertLessThan() assertLessThanOrEqual() assertNull() / assertNotNull() assertType() / assertNotType() assertSame() / assertNotSame() assertRegExp() / assertNotRegExp() assertArrayHasKey() / assertArrayNotHasKey() assertContains() / assertNotContains() assertContainsOnly() / assertNotContainsOnly() assertClassHasAttribute() / assertClassNotHasAttribute() assertClassHasStaticAttribute() / assertClassNotHasStaticAttribute() assertAttributeContains() / assertAttributeNotContains() assertObjectHasAttribute() / assertObjectNotHasAttribute() assertAttributeGreaterThan() assertAttributeGreaterThanOrEqual() assertAttributeLessThan() assertAttributeLessThanOrEqual() assertFileEquals() / assertFileNotEquals() assertFileExists() / assertFileNotExists() assertStringEqualsFile() / assertStringNotEqualsFile() assertEqualXMLStructure() assertXmlFileEqualsXmlFile() / assertXmlFileNotEqualsXmlFile() assertXmlStringEqualsXmlFile() / assertXmlStringNotEqualsXmlFile() assertXmlStringEqualsXmlString() / assertXmlStringNotEqualsXmlString() assertTag() assertThat()
Полный мануал есть там: http://www.phpunit.de/manual/3.7/en/writing-tests-for-phpunit.html И еще Zend расширяет этот списочек своими методами. Можно также найти что-то полезное в посте у Шевчука: http://anton.shevchuk.name/php/unit-tests-zend-framework-application/
Файл bootstrap.php я немножко поменял из-за того, что вносил в приложении изменения в index.php. Подключил в него index.php и убрал дублируемый код.
Значительной проблемой для меня оказался суперглобальный массив $_SERVER, который при запуске теста приложение в консоли не видит. Поэтому проверки с $_SERVER['REQUEST_URI'], $_SERVER['DOCUMENT_ROOT'] и даже путь “./” ломали тест. Пришлось объявить в bootstrap.php переменные этого массива:
<?php $_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['PHP_SELF'] = '/index.php'; $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['DOCUMENT_ROOT'] = '/var/www/soft-komi.ru/www'; $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . '/index.php'; $_SERVER['REQUEST_URI'] = '/'; require_once '../www/index.php'; require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance();
Как не пытался сделать это внутри теста или повлиять на значения - пока мне это не удалось. Может еще найду или додумаюсь как это сделать, хотя если не писать много сложных тестов, то можно обойтись и bootstrap.php .
У инструмента есть еще одна фитча - отчеты.
Чтобы посмотреть что это такое, мне пришлось установить xdebag, сделать чтоб это расширение загружалось и из консоли, а также в phpunit.xml добавить секцию как у Шевчука: [code]<logging> <log type="coverage-html" target="/var/www/soft-komi.ru/tests/reports/" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70" /> </logging>
После этого, при прохождении теста, утилита задумалась очень на долго (просто возмутительно долго) и сформировала в tests/reports 31,3 МБ html файлов.
В файлах можно посмотреть каждую строку приложения, которая покрашена в один из 3 цветов: зеленый если код был выполнен, оранжевый - не был выполнен, серый - мертвый код.
Также статистика - где сколько процентов какого код попало в какую категорию из перечисленных.
Это конечно красиво и просто замечательно, но я сразу вырубил эти медленные отчеты :)
И на последок выкладываю файл .so в zip
Приятной Вам работы!!!!