framework.zend.com
Stable релиз 2.0 / 1.12

Первый PHPUnit-тест для Zend Framework

К комментариям

В этой статье я расскажу как максимально просто и быстро начать применять PHPUnit для тестирования приложений на Zend Framework, т.е. как написать первый тест по типу "Hello, World".
В качестве ответа на вопрос: что такое PHPUnit и для чего он нужен рекомендую эту статью PHPUnit. Часть 01 Автоматические тесты.

Подготовка

Я исхожу из того, что Zend Framework уже установлен и работает корректно. Прежде чем приступить к написанию первого теста, надо установить PHPUnit.
Процесс установки для Linux описан в официальной документации, про установку под Windows написано здесь.

Структура каталогов

Если для создания проекта Вы пользовались Zend-Tools, то необходимые каталоги и базовые файлы у Вас уже должны быть созданы. В каталоге lib, должен быть каталог tests, в котором должен быть файл phpunit.xml и каталог application с файлом bootstrap.php. Схематично это выглядит так:

project
|-- lib
|
|--application
| |
| |--controllers
| |
| |--IndexController.php
|
|--tests
|
|--application
| |
| |--bootstrap.php
|
|--phpunit.xml

Эти файлы и каталоги можно создать вручную, если их еще нет.

Конфигурация

Все настроечные параметры тестов задаются в конфигурационном файле phpunit.xml
Вот минимальный текст этого файла:

<phpunit
bootstrap="./application/bootstrap.php"
>

<testsuite name="MyApp">
<directory>./</directory>
</testsuite>

</phpunit>

В конфигурации задается пусть к файлу bootstrap.php и набор тестов, см. PHPUnit. Часть 05 Организация тестов.
Сейчас у нас один набор, в который входя все тесты.

Файл bootstrap.php

Файл Bootstrap.php по своим функциям и содержанию почти полностью дублирует index.php.
Вот его содержимое:

<?php
error_reporting( E_ALL | E_STRICT );

define('BASE_PATH', realpath(dirname(__FILE__) . '/../../'));
define('APPLICATION_PATH', BASE_PATH . '/application');

set_include_path(
'.'
. PATH_SEPARATOR . BASE_PATH . '/library'
. PATH_SEPARATOR . get_include_path()
);

define('APPLICATION_ENV', 'testing');

require_once 'Zend/Application.php';
require_once 'ControllerTestCase.php';

В Bootstrap.php мы указываем пути, и подключаем файлы с нужными классами.

Файл ControllerTestCase.php

В этом файле находится абстрактный класс ControllerTestCase, от которого будут унаследованы все тесты.
Файл ControllerTestCase.php:

<?php

require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
protected $application;

public function setUp()
{
$this->bootstrap = array($this, 'appBootstrap');
parent::setUp();
}

public function appBootstrap()
{
$this->application = new Zend_Application(APPLICATION_ENV,APPLICATION_PATH . '/configs/application.ini');
$this->application->bootstrap();
}
}

Каждое MVC приложение должно надлежащим образом инициализировать переменную $this->bootstrap.
В документации описаны три возможных способа, выше использован один из них.

Ядро тестирования готово, можно написать первый тест.

И еще раз о структуре каталогов

В документации на PHPUnit приводится рекомендуемая структура организации тестов, см. PHPUnit. Часть 05 Организация тестов. Согласно рекомендациям, дерево каталогов тестов должно повторять дерево тестируемого приложения. Поэтому, для тестирования контроллеров в каталоге application создается каталог controllers, в котором будут создаваться тесты контроллеров.

    Классы и соответственно файлы unit-тестов должны именоваться согласно правилам:
  • Наименование тестирующего класса образуется путем добавления постфикса Test к наименованию тестируемого класса. Например тестируемый класс называется Class, тестирующий - ClassTest.
  • Наименования тестирующих методов образуются путем добавления приставки test к наименованиям тестируемых методов.

Поэтому для тестирования контроллера IndexController создается класс IndexControllerTest в файле IndexControllerTest.php.

Файл IndexControllerTest.php

Этот файл находится в каталоге application/controllers/
Файл IndexControllerTest.php:

<?php

class IndexControllerTest extends ControllerTestCase
{
public function testIndexAction()
{
$this->dispatch("/index/index");
$this->assertController("index");
$this->assertAction("index");
$this->assertResponseCode(200);
}
}

Как видите, класс наследует ControllerTestCase.
Для тестирования метода IndexAction контроллера IndexController создается функция testIndexAction.
Строго говоря, это не тестирование функционала, а простейший тест.
Тест заключается в том, что при обработки URL "/index/index" текущим котроллером должен стать контроллер index, текущим действием - действие index. Кроме этого проверяется, что ответный код HTML-запроса: 200 (ошибок нет).
Все PHPUnit-тесты стоятся на утверждениях (assert), см. примеры.
В этом тесте проверяются утверждения: assertController, assertAction, assertResponseCode.
Для успешного выполнения теста обязательно требуется выполнение всех утверждений.

Выполнение теста

Из каталога tests выполните команду phpunit. Если все хорошо Вы увидите такой результат:

PHPUnit 3.4.11 by Sebastian Bergmann.
.
Time: 9 seconds, Memory: 12.00Mb
OK (1 test, 3 assertions)

Итак, Вы видите, что принцип написания тестов весьма прост. В следующих статьях я рассмотрю особенности PHPUnit, имеющие больший практический смысл.

Источники
При написании статьи использовались материалы Unit Testing with the Zend Framework with Zend_Test and PHPUnit.

метки: PHPUnit, Zend_Test
Лучший способ следить за обновлениями сайта это подписаться на RSS
Если информация была полезной для вас, вы можете поддержать сайт.
Комментарии:
Илья 23.04.2010 07:48 #
>> Тест заключается в том, что при обработки URL "/index/index"

А почему не $this->dispatch("/"); ?
Ответить
Олег 14.06.2010 17:10 #
Здравствуйте.
Скажите, пожалуйтса, почему после запуска теста возникает ошибка:
Zend_Controller_Exception: No deafault module defined for this application?
Походил по форумам, но пока решения данной проблемы не нашел.
Всего наилучшего, пока.
Ответить
Уважаемые пользователи. Комментарии не для того чтобы:
  1. Спрашивать почему у вас не работает код, для этого есть тема форума закрепленная за статьей.
  2. Спрашивать как реализовать ту или иную функциональность, для этого необходимо создать свою тему на форуме.

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

Комментарии имеют древовидную структуру.
Если вы хотите ответить на определенный комментарий - нажмите на ссылку "Ответить" возле этого комментария.

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