6

ZF2で書かれた大きなサイトをテストする必要があります。443のテストと約10000のアサーションがあります。コードカバレッジを使用したテストには6時間かかります。私は問題を見つけたと思います:コントローラーのテストでは、AbstractHttpControllerTestCaseのディスパッチメソッドを使用します。ディスパッチメソッドの実行時間は、各テスト後に増加しています(数分の1秒から数十秒)。

ZF 2.1.3、PHPUnit 3.7、PHP_CodeCoverage 1.2、Xdebug v2.2.1、PHP5.4.7を使用しています。

私の派遣方法:

public function dispatch($url, $method = HttpRequest::METHOD_GET, $params = array())
{
    $s = microtime(true);

    parent::dispatch($url, $method, $params);

    $end = microtime(true) - $s;
    echo 'dis: '.$end."\n";

    return $this->getApplication()->getMvcEvent()->getResult();
}

parent :: dispatchは、AbstractHttpControllerTestCaseのメソッドです。

テストのサンプル:

$result = $this->dispatch('/archive/finance/older');

$this->assertControllerName('skycontent\controller\article');
$this->assertActionName('archive');
$this->assertParamValue('older', true);
$this->assertParamValue('category', 'finance');

$vars = (array) $result->getVariables();

$this->assertArrayHasKey('archivePosts', $vars);

助けてください。ありがとう。


アップデート:

プロセス分離と約15分で実行されたテスト(コードカバレッジなし)を使用していますが、スキップとしてマークされたテストでエラーが発生します:

PHPUnit_Framework_Exception: PHP Fatal error:  Uncaught exception 'Exception' with message 'Serialization of 'Closure' is not allowed' in -:44
4

1 に答える 1

2

Zend\ServiceManagerとの両方がクロージャーZend\EventManagerを多用します。アプリケーション インスタンス全体をシリアライズして、それが機能することを期待することはできません。これは、基本的に、クロージャーとして定義されたサービス ファクトリとイベント リスナーをシリアライズしようとすることを意味するためです。

解決策は、アプリケーション インスタンスをメモリに保持しないDoctrineORMModule のBootstrap.phpようなテストを使用することです。簡単な例を次に示します。

require_once __DIR__ . '/../vendor/autoload.php';

$appConfig = require __DIR__ . '/TestConfiguration.php';

\YourModuleTest\Util\ServiceManagerFactory::setConfig($appConfig);

unset($appConfig);

(標準の mvc アプリケーションの config のTestConfigurationように見えるはずです)

も必要ですServiceManagerFactory。サンプルの実装は、ここここにあります。

namespace YourModuleTest\Util;

class ServiceManagerFactory
{
    /**
     * @var array
     */
    protected static $config;

    /**
     * @param array $config
     */
    public static function setConfig(array $config)
    {
        static::$config = $config;
    }

    /**
     * Builds a new service manager
     * Emulates {@see \Zend\Mvc\Application::init()}
     */
    public static function getServiceManager()
    {
        $serviceManager = new ServiceManager(new ServiceManagerConfig(
            isset(static::$config['service_manager']) 
                ? static::$config['service_manager'] 
                : array()
        ));

        $serviceManager->setService('ApplicationConfig', static::$config);
        $serviceManager->setFactory(
            'ServiceListener',
            'Zend\Mvc\Service\ServiceListenerFactory'
        );

        /** @var $moduleManager \Zend\ModuleManager\ModuleManager */
        $moduleManager = $serviceManager->get('ModuleManager');
        $moduleManager->loadModules();

        return $serviceManager;
    }
}

これで、テストの好きな場所で次のことができます。

$serviceManager = \YourModuleTest\Util\ServiceManagerFactory::getServiceManager();
$application    = $serviceManager->get('Application');

$application->bootstrap();

// ...

このセットアップでは、断熱材でテストを実行できます。

一方、ZF2 は複雑なオブジェクトを構成する方法を非常に単純化するため、最初に実際の単体テストに集中する必要があります。また、関連のないコードが処理されないように、カバレッジ フィルターを正しく設定する必要があります (多くの時間を浪費する可能性があります)。

また、mvc アプリケーション インスタンスの再利用は間違っています。ヘルパーはステートレスではないため、再利用が難しくなります。

于 2013-03-13T15:10:04.133 に答える