web-dev-qa-db-fra.com

Comment afficher dans la CLI lors de l'exécution de PHP tests unitaires?

Lors de l'exécution d'un test PHPUnit, j'aimerais pouvoir vider la sortie afin de pouvoir déboguer une ou deux choses.

J'ai essayé ce qui suit (semblable au exemple du manuel PHPUnit );

class theTest extends PHPUnit_Framework_TestCase
{
    /**
     * @outputBuffering disabled
     */
    public function testOutput() {
        print_r("Hello World");
        print "Ping";
        echo "Pong";
        $out = "Foo";
        var_dump($out);
    }   
}

Avec le résultat suivant:

PHPUnit @package_version@ by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.00Mb

OK (1 test, 0 assertions)

Notez qu'il n'y a aucune des sorties attendues.

J'utilise les versions HEAD de git repos à compter du 19 septembre 2011.

Sortie de php -version:

$ php -version
PHP 5.2.9 (cli) (built: Dec  8 2010 11:36:37) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

Y a-t-il quelque chose que je fais mal ou est-ce potentiellement un bogue de PHPUnit?

125
Jess Telford

[~ # ~] met à jour [~ # ~]

Je viens de réaliser une autre façon de faire qui fonctionne beaucoup mieux que l’option de ligne de commande --verbose:

class TestSomething extends PHPUnit_Framework_TestCase {
    function testSomething() {
        $myDebugVar = array(1, 2, 3);
        fwrite(STDERR, print_r($myDebugVar, TRUE));
    }
}

Cela vous permet de tout transférer sur votre console à tout moment, sans toutes les sorties indésirables associées à l'option CLI --verbose.


Comme d'autres réponses l'ont noté, il est préférable de tester la sortie à l'aide des méthodes intégrées telles que:

$this->expectOutputString('foo');

Cependant, il est parfois utile d’être vilain et de voir la sortie de débogage unique/temporaire dans vos scénarios de test. Il n’est pas nécessaire pour le hack/solution de contournement var_dump, Cependant. Cela peut facilement être accompli en définissant l'option de ligne de commande --verbose Lors de l'exécution de votre suite de tests. Par exemple:

$ phpunit --verbose -c phpunit.xml

Cela affichera la sortie de vos méthodes de test lors de l'exécution dans l'environnement CLI.

Voir: Ecriture de tests pour PHPUnit - Test de la sortie .

158
rdlowrey

Mise à jour: Voir mise à jour de rdlowrey ci-dessous concernant l'utilisation de fwrite(STDERR, print_r($myDebugVar, TRUE)); comme un moyen beaucoup plus simple de contourner


Ce comportement est intentionnel (comme jasonbar a souligné ). L'état conflictuel du manuel a été rapporté à PHPUnit.

Une solution consiste à demander à PHPUnit d'affirmer que la sortie attendue est vide (en l'absence de sortie), ce qui déclenchera l'affichage de la sortie inattendue.

class theTest extends PHPUnit_Framework_TestCase
{
    /**
     * @outputBuffering disabled
     */
    public function testOutput() {
        $this->expectOutputString(''); // tell PHPUnit to expect '' as output
        print_r("Hello World");
        print "Ping";
        echo "Pong";
        $out = "Foo";
        var_dump($out);
    }   
}

donne:

PHPUnit @package_version@ by Sebastian Bergmann.

F

Time: 1 second, Memory: 3.50Mb

There was 1 failure:

1) theTest::testOutput
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-''
+'Hello WorldPingPongstring(4) "Foo"
+'

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Assurez-vous de désactiver toutes les autres assertions que vous avez pour le test, car elles risquent d'échouer avant que l'assertion de sortie ne soit testée (vous ne verrez donc pas le résultat).

32
Jess Telford

Essayez d'utiliser --debug

Utile si vous essayez de trouver le bon chemin vers un fichier de données include ou source.

27
chim

Ce n'est pas un bug, mais très intentionnel. Votre meilleur choix est d'écrire dans un fichier journal quelconque et d'ajuster le journal pour surveiller la sortie.

Si vous essayez de tester la sortie, vérifiez this out.

Aussi:

Remarque : Veuillez noter que PHPUnit engloutit toutes les sorties émises lors de l'exécution d'un test. En mode strict, un test qui émet une sortie échouera.

9
jasonbar

J'ai un peu de chance avec VisualPHPUnit , et il montre utilement la sortie, entre autres choses.

class TestHello extends PHPUnit_Framework_TestCase 
{
    public function test_Hello() 
    {
        print "hello world";
    }
}

TestHello results

7
Bob Stein

Vous devriez vraiment penser à vos intentions: si vous avez besoin des informations maintenant lors du débogage pour corriger le test, vous en aurez besoin de nouveau la semaine prochaine lorsque les tests se termineront.

Cela signifie que vous aurez besoin des informations toujours lorsque le test échouera - et de l'ajout d'un var_dump trouver la cause est trop de travail. Mettez plutôt les données dans vos assertions.

Si votre code est trop complexe pour cela, divisez-le jusqu'à atteindre un niveau où une assertion (avec un message personnalisé) vous en dit suffisamment pour savoir où il a été cassé, pourquoi et comment le corriger.

5
cweiske

Hackish, but works: Lance une exception avec la sortie de débogage comme message.

class theTest extends PHPUnit_Framework_TestCase
{
    public function testOutput() {
        throw new \Exception("hello");
    }   
}

Rendements:

...
There was 1 error:

1) theTest::testOutput
Exception: hello
3
Matthias Rella

Dans laravel 5, vous pouvez utiliser dump (), videz le contenu de la dernière réponse.

class ExampleTest extends TestCase{
    public function test1()
    {
        $this->post('/user', ['name' => 'Gema']);
        $this->dump();
    }
}

donne

3
Branny Bk

Dans certains cas, on pourrait utiliser quelque chose comme ça pour sortir quelque chose sur la console

class yourTests extends PHPUnit_Framework_TestCase
{
    /* Add Warnings */
    protected function addWarning($msg, Exception $previous = null)
    {
        $add_warning = $this->getTestResultObject();
        $msg = new PHPUnit_Framework_Warning($msg, 0, $previous);
        $add_warning->addWarning($this, $msg, time());
        $this->setTestResultObject($add_warning);
    }

    /* Add errors */
    protected function addError($msg, Exception $previous = null)
    {
        $add_error = $this->getTestResultObject();
        $msg = new PHPUnit_Framework_AssertionFailedError($msg, 0, $previous);
        $add_error->addError($this, $msg, time());
        $this->setTestResultObject($add_error);
    }

    /* Add failures */
    protected function addFailure($msg, Exception $previous = null)
    {
        $add_failure = $this->getTestResultObject();
        $msg = new PHPUnit_Framework_AssertionFailedError($msg, 0, $previous);
        $add_failure->addFailure($this, $msg, time());
        $this->setTestResultObject($add_failure);
    }

    public function test_messages()
    {
        $this->addWarning("Your warning message!");
        $this->addError("Your error message!");
        $this->addFailure("Your Failure message");
    }

    /* Or just mark test states! */
    public function test_testMarking()
    {
        $this->markTestIncomplete();
        $this->markTestSkipped();
    }
}
3
mkungla

Utilisez simplement le drapeau - verbose lorsque vous exécutez phpunit .

$ phpunit --verbose -c phpunit.xml 

L'avantage de cette méthode est que vous n'avez pas besoin de changer le code de test, vous pouvez imprimer des chaînes, tout ce que vous voulez de var_dump et ce sera affiché dans la console uniquement lorsque le mode verbose est défini .

J'espère que ça aide.

2
Fabricio

Ceci a été pris de Documentation PHPUnit sur les fixtures .

Cela devrait vous permettre de dumper les informations à tout moment du cycle de vie du test phpunit.

Il suffit de remplacer __METHOD__ dans le code ci-dessous avec tout ce que vous voulez afficher

Exemple 4.2: Exemple montrant toutes les méthodes de modèle disponibles

<?php
class TemplateMethodsTest extends PHPUnit_Framework_TestCase
{
    public static function setUpBeforeClass()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    protected function setUp()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    protected function assertPreConditions()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    public function testOne()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
        $this->assertTrue(TRUE);
    }

    public function testTwo()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
        $this->assertTrue(FALSE);
    }

    protected function assertPostConditions()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    protected function tearDown()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    public static function tearDownAfterClass()
    {
        fwrite(STDOUT, __METHOD__ . "\n");
    }

    protected function onNotSuccessfulTest(Exception $e)
    {
        fwrite(STDOUT, __METHOD__ . "\n");
        throw $e;
    }
}
?>
2
Chris

Je produis mes résultats de test en HTML, dans ce cas, il était utile de vider le contenu:

var_dump($array);
ob_flush();

Il existe une seconde PHP Méthode

flush() 

ce que je n'ai pas essayé.

1
Sudo

Je devais modifier le code source pour que ce code fonctionne, vous devez donc ajouter une URL pour cette mise en pension fourchue à composer pour que cela fonctionne

class TestCase extends \PHPUnit_Framework_TestCase
{
    /**
     *  Save last response
     * @var Response|null A Response instance
     */
    static $lastResponse;
    /**
     *  Modify to save response
     *
     * @param  string $method
     * @param  string $uri
     * @param  array $parameters
     * @param  array $files
     * @param  array $server
     * @param  string $content
     * @param  bool $changeHistory
     * @return \Illuminate\Http\Response
     */
    final public function call(
        $method,
        $uri,
        $parameters = [],
        $files = [],
        $server = [],
        $content = null,
        $changeHistory = true
    ) {

        $response = parent::call($method, $uri, $parameters, $files, $server, $content, $changeHistory);
        static::$lastResponse = $this->client->getResponse();
        return $response;
    }


    /**
     * Modify message to add response text
     *
     * @param mixed $value
     * @param PHPUnit_Framework_Constraint $constraint
     * @param string $message
     * @since  Method available since Release 3.0.0
     */
    final public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
    {
        $message .= PHP_EOL . static::$lastResponse . PHP_EOL;
        parent::assertThat($value, $constraint, $message);
    }
}
0
gadelkareem

Voici quelques méthodes utiles pour imprimer les messages de débogage dans PHPUnit 4.x:

  • syslog(LOG_DEBUG, "Debug: Message 1!");

    Exemple plus pratique:

    syslog(LOG_DEBUG, sprintf("%s: Value: %s", __METHOD__, var_export($_GET, TRUE)));
    

    L'appel syslog() générera un message de journal système (voir: man syslog.conf).

    Remarque: Niveaux possibles: LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, Etc.

    Sur macOS, pour diffuser les messages syslog en temps réel, exécutez:

    log stream --level debug --predicate 'processImagePath contains "php"'
    
  • fwrite(STDERR, "LOG: Message 2!\n");

    Note: La constante STDERR n’est pas disponible si vous lisez le script PHP de stdin . Voici le solution de contournement .

    Remarque: au lieu de STDERR, vous pouvez également spécifier un nom de fichier.

  • file_put_contents('php://stderr', "LOG: Message 3!\n", FILE_APPEND);

    Remarque: Utilisez cette méthode si vous n'avez pas défini STDERR constante .

  • register_shutdown_function('file_put_contents', 'php://stderr', "LOG: Message 4!\n", FILE_APPEND);

    Remarque: Utilisez cette méthode si vous souhaitez imprimer quelque chose à la fin sans affecter les tests.

Pour vider la variable, utilisez var_export(), par exemple. "Value: " . var_export($some_var, TRUE) . "\n".

Pour imprimer les messages ci-dessus uniquement en mode verbose ou débogage, voir: Existe-t-il un moyen de savoir si --debug ou --verbose a été passé à PHPUnit lors d'un test?


Cependant, si le test de la sortie fait partie du test it it-self, consultez: Testing Output page docs.

0
kenorb