使用 Zend 测试设置 PHPUnit

我正在尝试将 PHPUnit 与 Zend Test 一起用于我的 Zend Framework 应用程序.我可以从命令行 phpunit --configuration phpunit.xml 运行 PHPUnit 命令.我已尝试遵循 本教程这是基于 Matthew Weier O'Phinney 的 博文.当 PHPUnit 尝试写入日志文件时出现错误.这是我的 phpunit.xml

I'm trying to start using PHPUnit with Zend Test for my Zend Framework application. I'm able to run the PHPUnit command from command line phpunit --configuration phpunit.xml. I've tried following this tutorial which is based off of Matthew Weier O'Phinney's blog post. I'm getting an error when PHPUnit tries to write the log file. Here's my phpunit.xml

<phpunit bootstrap="./Bootstrap.php" colors="true">
    <testsuite name="Zend Framework Tests">
        <directory>./</directory>
    </testsuite>
    <!-- Optional filtering and logging settings -->
    <filter>
        <whitelist>
            <directory suffix=".php">../library/</directory>
            <directory suffix=".php">../application/</directory>
            <exclude>
                <directory suffix=".phtml">../application/</directory>
            </exclude>
        </whitelist>
    </filter>
    <logging>
        <log type="coverage-html" target="./log/report" charset="UTF-8" yui="true" highlight="true" lowUpperBound="50" highLowerBound="80"/>
        <log type="testdox-html" target="./log/testdox.html"/>
    </logging>
</phpunit>

我的测试引导程序:

<?php
//Set app paths and environment
define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_PATH', BASE_PATH . '/application');
define('TEST_PATH', BASE_PATH . '/tests');
define('APPLICATION_ENV', 'testing');
//Set include path
set_include_path('.' . PATH_SEPARATOR . BASE_PATH . '/library' . PATH_SEPARATOR . get_include_path());
//Set the default timezone
date_default_timezone_set('America/Chicago');
?>

还有我希望我的测试控制器扩展的 ControllerTestCase:

And my ControllerTestCase that I would like my testing controllers to extend:

<?php
require_once 'Zend/Application.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    public $_application;

    public function setUp()
    {
        //Override the parent to solve an issue with not finding the correct module
        $this->bootstrap = new Zend_Application(
            APPLICATION_ENV, 
            APPLICATION_PATH . '/configs/application.ini'
        );
        parent::setUp();
    }
}
?>

PHPUnit 尝试写入日志文件时出现的错误是:致命错误:第 38 行的 C:epositoriesmyfirstzend.comincludeslibraryDoctrineDBALToolsConsoleCommandImportCommand.php 中找不到类 'SymfonyComponentConsoleCommandCommand'

The error I get when PHPUnit tries to write the log file is: Fatal error: Class 'SymfonyComponentConsoleCommandCommand' not found in C:epositoriesmyfirstzend.comincludeslibraryDoctrineDBALToolsConsoleCommandImportCommand.php on line 38

关于我做错了什么的任何线索?我在 PHP 5.4、Windows 7、XAMPP 8.0 上,Pear 是最新的,我有最新的 PHPUnit.

Any clues on what I'm doing wrong? I'm on PHP 5.4, Windows 7, XAMPP 8.0, Pear is up to date, and I have the latest PHPUnit.

更新如果我将 Bootstrap.php 更改为 Matthew Weier O'Phinney 博客中的以下内容:

Update If I change my Bootstrap.php to the following from Matthew Weier O'Phinney's blog:

<?php
/*
 * Start output buffering
 */
ob_start();

/*
 * Set error reporting to the level to which code must comply.
 */
error_reporting( E_ALL | E_STRICT );

/*
 * Set default timezone
 */
date_default_timezone_set('GMT');

/*
 * Testing environment
 */
define('APPLICATION_ENV', 'testing');

/*
 * Determine the root, library, tests, and models directories
 */
$root        = realpath(dirname(__FILE__) . '/../');
$library     = $root . '/library';
$tests       = $root . '/tests';
$models      = $root . '/application/models';
$controllers = $root . '/application/controllers';

/*
 * Prepend the library/, tests/, and models/ directories to the
 * include_path. This allows the tests to run out of the box.
 */
$path = array(
    $models,
    $library,
    $tests,
    get_include_path()
);
set_include_path(implode(PATH_SEPARATOR, $path));

/**
 * Register autoloader
 */
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

/**
 * Store application root in registry
 */
Zend_Registry::set('testRoot', $root);
Zend_Registry::set('testBootstrap', $root . '/application/bootstrap.php');

/*
 * Unset global variables that are no longer needed.
 */
unset($root, $library, $models, $controllers, $tests, $path);

我继续从 Doctrine 收到有关 Symfony 的错误.我确保我也安装了 pear.symfony.com/Yaml.所以还是坏了.

I continue to get the error about Symfony from Doctrine. I ensured that I installed pear.symfony.com/Yaml as well. So still broken.

如果我从我正在测试的应用程序的 app.ini 中删除 Doctrine 引用(这意味着它不会被加载),我仍然会收到错误消息.几乎感觉这三个部分(PHPUnit、ZF、Doctrine)中的每一个的加载器都在互相争斗.有没有办法解决这个问题?

If I remove the Doctrine reference from my app.ini for the application I'm testing (which means it doesn't get loaded), I still get the error. It almost feels like the loaders for each of the three parts (PHPUnit, ZF, Doctrine) are fighting each other. Is there a way around this?

第二次更新:我将 PHPUnit 降级到 3.4.15,但我仍然遇到这个问题.我的下一步是从 PHP 5.4 升级到 5.3.x.

Second update: I downgraded PHPUnit to 3.4.15 and I'm still having this issue. My next step is to go from PHP 5.4 to 5.3.x.

第三次更新:我现在使用的是 PHP 5.3.10,并且看到了同样的错误.

Third update: I am now on PHP 5.3.10 and am seeing the same error.

如果您需要更多信息,请告诉我.

If there's more information you need, please let me know.

推荐答案

我在您的引导程序中缺少应用程序的加载.

I'm missing the loading of the application in your bootstrap.

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

让您了解我的 tests/bootstrap.php 中的内容(这是自 1.11.4 版以来由 zend 工具自动生成的)

To give you an idea about what I have in my tests/bootstrap.php (this is auto-generated by zend tool since release-1.11.4)

<?php

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();

正如 Zend Framework 手册所述,最好使用 PHPUnit 3.4.15,尽管我可以使用 PHPUnit 3.6.12 运行我的测试,因为我正在隔离我的测试以专注于我的业务逻辑而不是 Zend Framework 的逻辑.

As mentioned by the Zend Framework manual, best is to use PHPUnit 3.4.15 although I could run my tests using PHPUnit 3.6.12 as I'm isolating my tests to focus on my business logic and not the logic of Zend Framework.

我还将我的 phpunit.xml 修改为以下内容:

I also modified my phpunit.xml as well into the following:

<phpunit bootstrap="./bootstrap.php" colors="true">
    <testsuite name="Application Test Suite">
        <directory>./application</directory>
    </testsuite>
    <testsuite name="Library Test Suite">
        <directory>./library</directory>
    </testsuite>

    <filter>
        <whitelist>
            <directory suffix=".php">../../library</directory>
            <directory suffix=".php">../../application</directory>
            <exclude>
                <directory suffix=".php">../../library/Zend</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

我希望这可以解决您现在面临的许多问题.

I hope this solves many of your issues you're facing now.

最好的问候,

米开朗基罗

相关文章