Der Klassenfehler kann beim Generieren des PHPUnit-Codeabdeckungsberichts nicht erneut deklariert werden

Lesezeit: 8 Minuten

Starten eines Projekts mit Zend Framework 1.10 und Doctrine 2 (Beta1). Ich verwende Namespaces in meinem eigenen Bibliothekscode.

Beim Generieren von Codeabdeckungsberichten erhalte ich einen schwerwiegenden Fehler beim erneuten Deklarieren einer Klasse. Um weitere Informationen bereitzustellen, habe ich den xdebug_disable()-Aufruf in meiner ausführbaren phpunit-Datei auskommentiert, damit Sie den Funktionstrace sehen können (deaktivierte lokale Variablenausgabe, weil zu viel Ausgabe vorhanden war).

Hier ist meine Terminalausgabe:

$ 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

(Ich habe keine Ahnung, warum der Fehler zweimal angezeigt wird …?)

Und hier ist meine 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>

Ich habe ein Tag in das hinzugefügt, das dieses Problem zu verbergen scheint. Ich habe eine andere Anwendungsressource, aber es scheint kein Problem zu geben (die andere ist eine Doctrine 2-Ressource). Ich bin mir nicht sicher, warum es spezifisch für diese Klasse ist, meine gesamte Bibliothek wird automatisch geladen, sodass es nirgendwo irgendwelche include/require-Aufrufe gibt. Ich denke, es sollte angemerkt werden, dass HelperBroker die erste Datei im Dateisystem ist, die von library/Cob stammt

Ich verwende Snow Leopard mit den neuesten/neuesten Versionen aller Software (Zend Server, Zend Framework, Doctrine 2 Beta1, Phing, PHPUnit, PEAR).

  • Beim Bearbeiten von pear/PHPUnit/Framework/TestResult.php, um enthaltene Dateien zu kopieren, scheint es aus irgendeinem Grund, dass die fragliche Datei Helperbroker.php und nicht HelperBroker.php enthält! (Die Datei ist tatsächlich HelperBroker.php), weshalb die include_once-Anweisung in TestResult.php immer noch versuchte, die Datei zu laden. Alle anderen Dateien, die enthalten sind, haben die richtige Groß- und Kleinschreibung. Ich werde jetzt untersuchen, warum bei der Datei die Groß-/Kleinschreibung nicht beachtet wird

    – Cobby

    12. Mai 2010 um 6:09 Uhr


  • Es scheint, dass die Standard-Namenskonvention für Zend Framework-Plugins (die Zend_Application-Ressourcen enthalten) ucfirst() ist und nicht camelCase wie normale Bibliotheksdateien. Das Umbenennen der Datei in Helperbroker.php behebt das Problem.

    – Cobby

    12. Mai 2010 um 6:34 Uhr

  • Schreibe deine Antwort als Antwort und akzeptiere sie, so hat die Frage hier einen Platz und kann auch anderen helfen!

    – Markus

    12. November 2011 um 16:01 Uhr

  • @alexander-v-ilyin Was erwarten Sie von der Antwort, die für das Kopfgeld gilt? Op scheint sein Problem einigermaßen gelöst zu haben, aber man könnte eine allgemeine Antwort schreiben, wie man diesen Fehler beseitigt, oder so. Wie sind die Antworten veraltet und was ist das aktuelle Problem 🙂

    – edorisch

    22. November 2011 um 20:53 Uhr


Benutzer-Avatar
edorian

Allgemeine Antwort zum Abschluss dieses Problems:

Diese Fehlermeldung weist normalerweise auf ein Problem mit dem automatischen Laden und/oder Erfordernis-Anweisungen hin.

Während der Code-Coverage-Berichterstellung ist phpunit requirejeden *.php das ist in <whitelist>. Dies kann mit abgeschaltet werden addUncoveredFilesFromWhitelist=false als Parameter, aber es wird empfohlen, dies eingeschaltet zu lassen.

Mögliche Gründe

Was in diesen Fällen passiert, ist, dass eine der Dateien eine require -Anweisung, die eine bereits geladene Klasse erneut erfordert (da es sich nicht um require_once handelt).

Andere Gründe können sein

  • die doppelte Definition von Klassen (eine zum Debuggen, eine für die Produktion, sollte durch Vererbung gelöst werden, nicht durch Laden der richtigen PHP-Datei)

  • Inkonsistente Großschreibung führt zu Fehlern im PHP-Code wie:

    if( !$classesLoaded['ThIsClass']) require_once(...); an mehreren Stellen mit unterschiedlicher Großschreibung.

  • Die Klasse wurde in den Tests überhaupt nicht geladen, aber es wurde ein Scheinobjekt mit dem Namen der dann geladenen Klasse erstellt. Diese können kollidieren und ebenfalls zu diesem Fehler führen

  • In meinem Fall passiert an der Stelle “require_once” fatal, daher verstehe ich nicht wirklich, warum dies möglich ist.

    – Alexander V. Iljin

    25. November 2011 um 12:06 Uhr

  • @AlexanderV.Ilyin Fügen Sie eine debug_backtrace in die Datei ein, die die Klasse deklariert, und eine in die Datei, die sie erfordert (“erneut”), und sehen Sie, ob das hilft. Nur um es “schnell” loszuwerden, können Sie die Datei aus der weißen Liste ausschließen und sehen, ob das hilft und Sie auf den richtigen Weg bringt.

    – edorisch

    25. November 2011 um 13:03 Uhr

  • @AlexanderV.Ilyin werfen Sie auch einen Blick auf @XDebug – es bietet nette Stack-Traces für alle PHP-Fehler / Ausnahmen. (Ich wünschte jedoch, XDebug wäre CLI-fähig – das Scannen von HTML-Tabellen nach Stack-Details in der Konsole wird ermüdend und 4 Uhr morgens) – sieht so aus, als ob XDebug CLI besser unterstützt, als ich dachte: derickrethans.nl/cli-color.html

    – Bob Gregor

    11. November 2013 um 18:25 Uhr


  • Bei Verwendung von Autoloading – dh bei Verwendung von Composer – reicht es aus, eine Klasse mit unterschiedlicher Groß-/Kleinschreibung aufzurufen, um diesen Fehler auszulösen! Ich bin darüber gestolpert, weil eine Klasse angerufen hat WhitespaceTokenizer wurde testweise per angerufen new WhiteSpaceTokenizer. Das Ergebnis war eine völlig fehlende Codeabdeckung für diese Klasse.

    – heiglandreas

    8. Januar 2014 um 14:28 Uhr


  • Aktualisieren von PHPUnit über composer update Dinge für mich behoben, also gibt es vielleicht ein paar Dinge in PHPUnit, die sich mit dem automatischen Laden von Dateien zwischen den Versionen befassen. Es ist wahrscheinlich eine naheliegende Sache, es zu versuchen, aber nur für den Fall, dass jemand ähnliche Probleme hat.

    – Leggetter

    13. Mai 2015 um 13:01 Uhr

Eine weitere zu prüfende Sache (insbesondere wenn Sie mit einer VM arbeiten) ist, ob eine Datei umbenannt wurde, aber noch in der ursprünglichen Form existiert. z.B. fooMapper.php in FooMapper.php umbenannt (z. B. per SVN-Update), erkennt Ihre IDE die neue Datei und sendet sie an die VM. Sie haben jetzt beide Versionen auf Ihrer VM, auch wenn Ihre IDE lokal nur eine anzeigt. In acht nehmen.

Eine schnelle Problemumgehung besteht möglicherweise darin, am Anfang Ihrer Klassendeklaration eine if-Anweisung hinzuzufügen, um eine erneute Deklaration beim Ausführen von phpunit zu vermeiden (wenn und nur wenn dies die einzige Klasse ist, mit der Sie Probleme haben).

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

  • Dies fügt zu viel Komplexität hinzu, indem die Folgen eines Fehlers “ungültig gemacht” werden, anstatt den eigentlichen Fehler zu verstehen und zu beheben.

    – Xenos

    11. November 2016 um 16:32 Uhr

Ich hatte ein ähnliches Problem, weil ich alle Dateien für die Abdeckungsanweisungen verwendet habe. Als ich ein konkretes Verzeichnis und benötigte Dateien einstellte, war mein Problem gelöst.

Ich denke dein Problem liegt hier:

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

Hier benötigen Sie alle Dateien und Verzeichnisse.

Probieren Sie diesen Fall aus, um nur Tests anzufordern (oder legen Sie Ihre Ordner fest):

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

Sie können auch Präfixe, Suffixe und Dateien verwenden:

Das ist mir passiert, weil ich einen Tippfehler in meiner @covers-Erklärung hatte. Beachten Sie das zusätzliche \ in der ersten Zeile.

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

VS

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

Benutzer-Avatar
Damiankloip

Ich habe festgestellt, dass ich diesen Fehler erhalten habe, als ein falsch @coversDefaultClass (gleiches gilt wahrscheinlich für @covers too) Annotation verwendet wurde. In meinem Fall war es \Path\To\\Class (mit doppeltem ‘\’), was mit den erforderlichen Aufrufen durcheinander kam.

1105560cookie-checkDer Klassenfehler kann beim Generieren des PHPUnit-Codeabdeckungsberichts nicht erneut deklariert werden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy