Setup PHPUnit with Zend Test

2019-04-28 01:53发布

问题:

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>

My testing bootstrap:

<?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');
?>

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();
    }
}
?>

The error I get when PHPUnit tries to write the log file is: Fatal error: Class 'Symfony\Component\Console\Command\Command' not found in C:\repositories\myfirstzend.com\includes\library\Doctrine\DBAL\Tools\Console\Command\ImportCommand.php on line 38

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.

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);

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

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?

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.

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.

回答1:

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

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

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();

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.

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.

Best regards,

Michelangelo