Содержание


Unit-тесты


Unit Testing, Модульное тестирование , ЗФ2, Zend Framework 2, ZF2




Unit-тесты имеют важное значение в разработке крупных проектов, особенно с большим количеством вовлеченных людей. Проверять вручную каждый отдельный компонент приложения после каждого изменения нецелесообразно. Unit-тесты помогут облегчить разработку за счет автоматического тестирования компонентов Вашего приложения и предупредить, когда что-то не работает так, как задумывалось изначально.

Zend Framework 2 API использует PHPUnit, так же как и приложение в этом руководстве. Подробное описание модульного тестирования выходит за рамки этого руководства, поэтому далее будут использоваться только примеры тестов для компонентов. Это руководство предполагает, что у Вас уже установлен PHPUnit.

 


Настройка каталога для тестов
 

 

Начните с создания каталога testв zf2-tutorialmoduleApplicationс соответствующими подкаталогами:

zf2-tutorial/
    /module
        /Application
            /test
                /ApplicationTest
                    /Controller

Структура каталога testточно совпадает со структурой файлов исходного модуля, что позволяет сделать Ваши тесты структурированными и легко находимыми при поиске.

 


Начальная загрузка тестов

 

Следующим шагом, создайте файл с именем phpunit.xml.distв zf2-tutorial/module/Application/test:

<?xml version="1.0" encoding="UTF-8"?>
 
<phpunit bootstrap="Bootstrap.php">
    <testsuites>
        <testsuite name="zf2tutorial">
            <directory>./ApplicationTest</directory>
        </testsuite>
    </testsuites>
</phpunit>

Далее создайте файл Bootstrap.php в каталоге zf-tutorial/module/Application/test: Можете использовать ниже приведенный код, написанный Эваном Коури – Вам необходимо будет лишь изменить название пространства имен.

<?php
namespace ApplicationTest;//Change this namespace for your test
 
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;
 
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
 
class Bootstrap
{
    protected static $serviceManager;
    protected static $config;
    protected static $bootstrap;
 
    public static function init()
    {
        // Load the user-defined test configuration file, if it exists; otherwise, load
        if (is_readable(__DIR__ . '/TestConfig.php')) {
            $testConfig = include __DIR__ . '/TestConfig.php';
        } else {
            $testConfig = include __DIR__ . '/TestConfig.php.dist';
        }
 
        $zf2ModulePaths = array();
 
        if (isset($testConfig['module_listener_options']['module_paths'])) {
            $modulePaths = $testConfig['module_listener_options']['module_paths'];
            foreach ($modulePaths as $modulePath) {
                if (($path = static::findParentPath($modulePath)) ) {
                    $zf2ModulePaths[] = $path;
                }
            }
        }
 
        $zf2ModulePaths  = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
        $zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');
 
        static::initAutoloader();
 
        // use ModuleManager to load this module and it's dependencies
        $baseConfig = array(
            'module_listener_options' => array(
                'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
            ),
        );
 
        $config = ArrayUtils::merge($baseConfig, $testConfig);
 
        $serviceManager = new ServiceManager(new ServiceManagerConfig());
        $serviceManager->setService('ApplicationConfig', $config);
        $serviceManager->get('ModuleManager')->loadModules();
 
        static::$serviceManager = $serviceManager;
        static::$config = $config;
    }
 
    public static function getServiceManager()
    {
        return static::$serviceManager;
    }
 
    public static function getConfig()
    {
        return static::$config;
    }
 
    protected static function initAutoloader()
    {
        $vendorPath = static::findParentPath('vendor');
 
        if (is_readable($vendorPath . '/autoload.php')) {
            $loader = include $vendorPath . '/autoload.php';
        } else {
            $zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));
 
            if (!$zf2Path) {
                throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
            }
 
            include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
 
        }
 
        AutoloaderFactory::factory(array(
            'ZendLoaderStandardAutoloader' => array(
                'autoregister_zf' => true,
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
                ),
            ),
        ));
    }
 
    protected static function findParentPath($path)
    {
        $dir = __DIR__;
        $previousDir = '.';
        while (!is_dir($dir . '/' . $path)) {
            $dir = dirname($dir);
            if ($previousDir === $dir) return false;
            $previousDir = $dir;
        }
        return $dir . '/' . $path;
    }
}
 
Bootstrap::init();

Также создайте файл TestConfig.php.dist

<?php
return array(
    'modules' => array(
        'Application',
    ),
    'module_listener_options' => array(
        'config_glob_paths'    => array(
            '../../../config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            'module',
            'vendor',
        ),
    ),
);

Этот файл похож на Config/application.config.php с той лишь разницей, что в TestConfig.php.dist определяются только те модули, которые необходимы для этого теста.

 


Ваш первый тест Контроллера

 

Далее создайте IndexControllerTest.php вкаталоге zf-tutorial/module/Application/test/ApplicationTest/Controller соследующимсодержанием:

<?php
 
namespace ApplicationTestController;
 
use ApplicationTest\Bootstrap;
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter;
use Application\Controller\IndexController;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use PHPUnit_Framework_TestCase;
 
class IndexControllerTest extends PHPUnit_Framework_TestCase
{
    protected $controller;
    protected $request;
    protected $response;
    protected $routeMatch;
    protected $event;
 
    protected function setUp()
    {
        $serviceManager = Bootstrap::getServiceManager();
        $this->controller = new IndexController();
        $this->request    = new Request();
        $this->routeMatch = new RouteMatch(array('controller' => 'index'));
        $this->event      = new MvcEvent();
        $config = $serviceManager->get('Config');
        $routerConfig = isset($config['router']) ? $config['router'] : array();
        $router = HttpRouter::factory($routerConfig);
 
        $this->event->setRouter($router);
        $this->event->setRouteMatch($this->routeMatch);
        $this->controller->setEvent($this->event);
        $this->controller->setServiceLocator($serviceManager);
    }
}
Здесь мы немного расширяем запись в блоге Тома Орама «Модульное тестирование контроллера в ZF 2» путем инициализации нашего приложения в методе setUp() и установки EventManager и ServiceLocator прямо в контроллере. Это нам понадобится в дальнейшем, когда мы будем писать более сложные тесты. Теперь добавьте следующий метод в класс IndexControllerTest:
public function testIndexActionCanBeAccessed()
{
    $this->routeMatch->setParam('action', 'index');
 
    $result   = $this->controller->dispatch($this->request);
    $response = $this->controller->getResponse();
 
    $this->assertEquals(200, $response->getStatusCode());include/span/span
}

Этот тест проверяет то, что главная страница возвращает код состояния HTTPравный 200, и что возвращаемое контроллером значение является экземпляром Zend/View/Model/ViewModel.

 


Тестирование

 

И наконец-то Вы можете перейти в каталог zf-tutorial/module/Application/test/ и запустить phpunit. Если Вы видите что-то наподобие этого, то Ваше приложение готово к тестированию!


PHPUnit 3.5.15 by Sebastian Bergmann.
 
.
 
Time: 0 seconds, Memory: 5.75Mb
 
OK (1 test, 2 assertions)

Автор статьи: DuB