111 votes

Tester les en-têtes PHP avec PHPunit

Je suis en train d'utiliser PHPunit pour tester une classe qui affiche des en-têtes personnalisés.

Le problème est que sur ma machine ce:

<?php

class HeadersTest extends PHPUnit_Framework_TestCase {

    public function testHeaders()
    {
        ob_start();

        header('Location: foo');
        $headers_list = headers_list();
        header_remove();

        ob_clean();

        $this->assertContains('Location: foo', $headers_list);
    }
}

ou encore ceci:

<?php

class HeadersTest extends PHPUnit_Framework_TestCase {

    public function testHeaders()
    {
        ob_start();

        header('Location: foo');
        header_remove();

        ob_clean();
    }
}

renvoie cette erreur:

name@host [~/test]# phpunit --verbose HeadersTest.php 
PHPUnit 3.6.10 by Sebastian Bergmann.

E

Time: 0 seconds, Memory: 2.25Mb

There was 1 error:

1) HeadersTest::testHeaders
Cannot modify header information - headers already sent by (output started at /usr/local/lib/php/PHPUnit/Util/Printer.php:173)

/test/HeadersTest.php:9

FAILURES!
Tests: 1, Assertions: 0, Errors: 1.

C'est comme si il y a quelque chose d'autre de la sortie du terminal avant le test s'exécute même s'il n'y a pas d'autre fichier inclus et il n'y a aucun autre personnage avant le début de la balise PHP. Pourrait-il être quelque chose à l'intérieur de PHPunit qui en est la cause?

Quelle pourrait-être la question?

136voto

SamHennessy Points 1736

Le problème est que PHPUnit imprimera un en-tête à l’écran et qu’à ce stade, vous ne pourrez plus en ajouter.

La solution consiste à exécuter le test dans un processus isolé. Voici un exemple

 <?php

class FooTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testBar()
    {
        header('Location : http://foo.com');
    }
}
 

Cela se traduira par:

 $ phpunit FooTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

.

Time: 1 second, Memory: 9.00Mb

OK (1 test, 0 assertions)
 

La clé est l'annotation @runInSeparateProcess.

112voto

joonty Points 5652

Bien que l’exécution du test dans un processus distinct résolve le problème, il existe un temps système considérable lors de l’exécution d’une vaste suite de tests.

Ma solution était de diriger la sortie de phpunit vers stderr, comme ceci:

 phpunit --stderr <options>
 

Cela devrait résoudre le problème. Cela signifie également que vous n'avez pas à créer de fonction wrapper et à remplacer toutes les occurrences de votre code.

3voto

Sergio Abreu Points 399

J'avais une solution plus radicale, afin d'utiliser $_SESSION dans mes fichiers testés / inclus . J'ai édité l'un des fichiers PHPUnit à l' adresse ../PHPUnit/Utils/Printer.php pour avoir un "session_start();" avant la commande "print $ buffer" .

Cela a fonctionné pour moi comme un charme. Mais je pense que la solution de l'utilisateur "joonty" est la meilleure de toutes jusqu'à maintenant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X