簡體   English   中英

生成 PHPUnit 代碼覆蓋率報告時無法重新聲明類錯誤

[英]Cannot redeclare class error when generating PHPUnit code coverage report

使用 Zend Framework 1.10 和 Doctrine 2 (Beta1) 啟動項目。 我在自己的庫代碼中使用命名空間。

生成代碼覆蓋率報告時,我收到有關重新聲明類的致命錯誤。 為了提供更多信息,我在我的 phpunit 可執行文件中注釋掉了 xdebug_disable() 調用,以便您可以看到函數跟蹤(禁用局部變量輸出,因為輸出太多)。

這是我的終端輸出:

$ phpunit
PHPUnit 3.4.12 by Sebastian Bergmann.

........

Time: 4 seconds, Memory: 16.50Mb

OK (8 tests, 14 assertions)

Generating code coverage report, this may take a moment.PHP Fatal error:  Cannot redeclare class Cob\Application\Resource\HelperBroker in /Users/Cobby/Sites/project/trunk/code/library/Cob/Application/Resource/HelperBroker.php on line 93
PHP Stack trace:
PHP   1. {main}() /usr/local/zend/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/local/zend/bin/phpunit:54
PHP   3. PHPUnit_TextUI_Command->run() /usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:146
PHP   4. PHPUnit_TextUI_TestRunner->doRun() /usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:213
PHP   5. PHPUnit_Util_Report::render() /usr/local/zend/share/pear/PHPUnit/TextUI/TestRunner.php:478
PHP   6. PHPUnit_Framework_TestResult->getCodeCoverageInformation() /usr/local/zend/share/pear/PHPUnit/Util/Report.php:97
PHP   7. PHPUnit_Util_Filter::getFilteredCodeCoverage() /usr/local/zend/share/pear/PHPUnit/Framework/TestResult.php:623

Fatal error: Cannot redeclare class Cob\Application\Resource\HelperBroker in /Users/Cobby/Sites/project/trunk/code/library/Cob/Application/Resource/HelperBroker.php on line 93

Call Stack:
    0.0004     322888   1. {main}() /usr/local/zend/bin/phpunit:0
    0.0816    4114628   2. PHPUnit_TextUI_Command::main() /usr/local/zend/bin/phpunit:54
    0.0817    4114964   3. PHPUnit_TextUI_Command->run() /usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:146
    0.1151    5435528   4. PHPUnit_TextUI_TestRunner->doRun() /usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:213
    4.2931   16690760   5. PHPUnit_Util_Report::render() /usr/local/zend/share/pear/PHPUnit/TextUI/TestRunner.php:478
    4.2931   16691120   6. PHPUnit_Framework_TestResult->getCodeCoverageInformation() /usr/local/zend/share/pear/PHPUnit/Util/Report.php:97
    4.2931   16691148   7. PHPUnit_Util_Filter::getFilteredCodeCoverage() /usr/local/zend/share/pear/PHPUnit/Framework/TestResult.php:623

(我不知道為什么它會顯示兩次錯誤......?)

這是我的 phpunit.xml:

<phpunit bootstrap="./code/tests/application/bootstrap.php" colors="true">
    <!-- bootstrap.php changes directory to trunk/code/tests,
    all paths below are relative to this directory. -->

    <testsuite name="My Promotions">
        <directory>./</directory>
    </testsuite>

    <filter>
        <whitelist>
            <directory suffix=".php">../application</directory>
            <directory suffix=".php">../library/Cob</directory>
            <exclude>
                    <!-- By adding the below line I can remove the error -->
                <file>../library/Cob/Application/Resource/HelperBroker.php</file>
                <directory suffix=".phtml">../application</directory>
                <directory suffix=".php">../application/doctrine</directory>
                <file>../application/Bootstrap.php</file>
                <directory suffix=".php">../library/Cob/Tools</directory>
            </exclude>
        </whitelist>
    </filter>

    <logging>
        <log type="junit" target="../../build/reports/tests/report.xml" />
        <log type="coverage-html" target="../../build/reports/coverage" charset="UTF-8"
            yui="true" highlight="true" lowUpperBound="50" highLowerBound="80" />
    </logging>
</phpunit>

我在哪個接縫中添加了一個標簽來隱藏這個問題。 我確實有另一個應用程序資源,但沒有問題(另一個是 Doctrine 2 資源)。 我不確定為什么它特定於這個類,我的整個庫都是自動加載的,所以它們在任何地方都沒有任何包含/要求調用。 我想應該注意 HelperBroker 是文件系統中第一個源自 library/Cob 的文件

我在 Snow Leopard 上使用所有軟件的最新/最近版本(Zend Server、Zend Framework、Doctrine 2 Beta1、Phing、PHPUnit、PEAR)。

解決這個問題的一般答案:

此錯誤消息通常指向自動加載和/或需要語句的問題。

在代碼覆蓋率報告生成期間,phpunit require <whitelist> whiteelist <whitelist>每個*.php 可以使用addUncoveredFilesFromWhitelist=false作為參數關閉此功能,但建議保持此功能。

可能的原因

在這些情況下往往會發生的情況是其中一個文件的require語句需要再次加載一個類(因為它不是require_once)。

其他原因可以

  • 類的重復定義(一個用於調試一個用於生產,應該通過繼承而不是通過加載正確的php文件來解決)
  • 不一致的大寫導致PHP代碼中的錯誤,如:

    if( !$classesLoaded['ThIsClass']) require_once(...); 在不同大寫的多個地方。

  • 該類在測試中根本沒有加載,但是使用當時加載的類的名稱創建了一個模擬對象。 那些可能會發生碰撞並導致錯誤

要檢查的另一件事(特別是如果您正在使用VM)是文件是否已重命名但仍以原始形式存在。 例如。 fooMapper.php重命名為FooMapper.php(例如通過SVN更新),IDE會檢測到新文件並將其發送到VM。 您現在在VM上有兩個版本,即使您的IDE本地只顯示一個版本。 謹防。

一個快速的解決方法可能是在你的類聲明的開頭添加一個if語句,以避免在運行phpunit時重新聲明(如果,並且只有當這是你遇到問題的唯一類時)

if (!class_exists("class_name")) {
    // declare the class
    class class_name
    {
        //...
    }
}

這件事發生在我身上,因為我的@covers宣言中有一個拼寫錯誤。 注意第一行中的額外\\。

App\Controller\\Account\UsersController::forgotPassword()

VS

App\Controller\Account\UsersController::forgotPassword()

我發現當我使用了錯誤的 @coversDefaultClass (同樣可能適用於@covers )時,我收到了這個錯誤。 在我的情況下,它是\\Path\\To\\\\Class (帶有雙'\\'),它正在弄亂require調用。

我遇到了類似的問題,因為我將所有文件都用於覆蓋說明。 當我設置具體目錄和所需文件時,我的問題就解決了。

我認為你的問題在這里:

<testsuite name="My Promotions">
    <directory>./</directory>
</testsuite>

在這里您需要所有文件和目錄。

試試這個案例只需要測試(或設置你的文件夾):

<testsuite name="My Promotions">
    <directory>tests</directory>
</testsuite>

您還可以使用前綴、后綴和文件:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM