Unit testing 使用PHPUnit测试模块化Zend框架应用程序

Unit testing 使用PHPUnit测试模块化Zend框架应用程序,unit-testing,zend-framework,phpunit,Unit Testing,Zend Framework,Phpunit,我有一个带有模块的Zend Framework应用程序,我想设置PHPUnit测试 这是项目文件夹 - project/ -application/ - controllers/ - indexController.php - modules/ - mycore/ - controllers/ - ActionsController.php - v

我有一个带有模块的Zend Framework应用程序,我想设置PHPUnit测试

这是项目文件夹

- project/
   -application/
      - controllers/
          - indexController.php
      - modules/
         - mycore/
            - controllers/
                -  ActionsController.php
            - views/
                - ...
   - ...
   - tests/
      - application/
         - controllers/
            -IndexControllerTest.php
         - modules/
            - mycore/
                - controllers/
                   - ActionsControllerTest.php
      ControllerTestCase.php
      Bootstrap.php
      phpunit.xml
这是测试文件夹中每个设置文件的内容

ControllerTestCase.php

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

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');
        $bootstrap = $this->application->getBootstrap()->bootstrap();

        $front = Zend_Controller_Front::getInstance();
        $front->setControllerDirectory(APPLICATION_PATH . '/controllers','default');
        $front->addModuleDirectory(APPLICATION_PATH . '/modules');

        return $bootstrap;
    }

    public function tearDown() {
        Zend_Auth::getInstance()->clearIdentity();
        $this->resetRequest();
        $this->resetResponse();
        parent::tearDown();
    }

    protected  function _doLogin($identity = null) {
        if ( $identity === null ) {
            $identity = $this->_generateFakeIdentity();
        }
        Zend_Auth::getInstance()->getStorage()->write( $identity );
    }

    protected function _generateFakeIdentity() {
        $identity = new stdClass();
        $identity->RecID                     = 3;
        $identity->user_firstname            = '****';
        $identity->user_lastname             = '********';
        $identity->confirmed                 = true;
        $identity->enabled                   = true;

        return $identity;
    }

    protected  function _doLogout() {
        Zend_Auth::getInstance()->clearIdentity();
    }
}
Bootstrap.php

error_reporting(E_ALL);
// 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') : 'development'));

// 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';
phpunit.xml

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

    <filter>
        <!-- If Zend Framework is inside your project's library, uncomment this filter -->
        <!-- 
        <whitelist>
            <directory suffix=".php">../../library/Zend</directory>
        </whitelist>
        -->
    </filter>
</phpunit>
这就是结果:

Starting test 'IndexControllerTest::testIndexAction'.
.
Starting test 'Mycore_ActionsControllerTest::testIndexAction'.
F

Time: 1 second, Memory: 14.00Mb

There was 1 failure:

1) Mycore_ActionsControllerTest::testIndexAction
Failed asserting last module used <"default"> was "mycore"

/project/library/Zend/Test/PHPUnit/ControllerTestCase.php:929
/project/tests/application/modules/mycore/controllers/ActionsControllerTest.php:21
启动测试“IndexController测试::testIndexAction”。
.
正在启动测试“Mycore\u ActionsControllerTest::testIndexAction”。
F
时间:1秒,内存:14.00Mb
有1次失败:
1) Mycore_ActionsControllerTest::testIndexAction
无法断言最后使用的模块是“mycore”
/project/library/Zend/Test/PHPUnit/ControllerTestCase.php:929
/project/tests/application/modules/mycore/controllers/ActionsControllerTest.php:21
模块内的所有测试都工作正常,但当我开始测试模块控制器时,我会出现此错误。
我已经在互联网上搜索过了,但是找不到修复此错误的方法,所以我希望有人能帮助我。

您得到的不是错误,而是测试失败

这可能是因为您正在调度到“/”,它在默认模块的默认控制器中查找默认操作。如果发送到“/mycore”或“/mycore/actions/index”,您可能会发现测试通过

要通过测试而不更改它,您需要指向“/mycore/actions/index”。

我也遇到了同样的问题。 对我来说,这是因为请求被重定向到“ErrorController”。 您可以通过注释assertModule行来检查这一点。 如果您遇到这样一个错误“无法断言最后一个使用的控制器是“操作”,那么我们的情况是相同的。 这类错误可能有多种原因。 你必须抓住错误。 发送后,您可以如下方式检索异常:

$response = $this->getResponse();
$exceptions = $response->getException();
// do whatever you want, mail, log, print

这就解释了为什么它不能正常工作。但是我对我的测试用例做了一些更改,所以我将分派到/mycore/actions/index(应用程序应该重定向到/user/login)。但是现在,如果我检查模块‘mycore’控制器‘actions’和动作‘index’,测试不会失败。我甚至没有得到任何回应(否或F或E)。我如何调试它以获得清晰的错误消息?提前谢谢!这意味着考试通过了。您似乎没有在phpunit.xml中设置任何日志记录。看一看。当考试通过时,你不是得到“.”吗?索引控制器获取一个。这一个没有任何反应。好的,我刚看到你的编辑,我会检查一下。谢谢我添加了loggin部分,对于常规索引控制器,它看起来通过了(我得到了IndexController-->IndexController测试,但是对于Mycore\u ActionsController,我什么都没有得到。所以没有通过测试?但是没有调试信息。我还使用了phpunit的可视化界面,这给了我一个错误“断言使用的最后一个模块失败”用户“因此模块仍然存在问题。是否还有其他方法可以从phpunit获取当前页面?这样我可以检查重定向是否正常。谢谢!您可以像在任何php文件中一样在测试中回显任何内容。类似于
回显“我在这里”;
的内容将出现在phpunit输出中。
$response = $this->getResponse();
$exceptions = $response->getException();
// do whatever you want, mail, log, print