PHPUnit: возможен вывод CLI во время тестовой отладки?

При запуске теста PHPUnit я хотел бы иметь возможность выгружать вывод, чтобы я мог отлаживать одну или две вещи.

Я пробовал следующее (похожее на пример PHPUnit Manual);

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

Со следующим результатом:

PHPUnit @[email protected] by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.00Mb

OK (1 test, 0 assertions)

Обратите внимание, что нет ожидаемого результата.

Я использую версии HEAD git repos по состоянию на 19 сентября 2011 года.

Вывод 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

Есть ли что-то, что я делаю неправильно, или это потенциально ошибка PHPUnit?

Ответ 1

UPDATE

Только что реализовал другой способ сделать это, который работает намного лучше, чем опция командной строки --verbose:

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

Это позволяет сбрасывать все на консоль в любое время без всякого нежелательного вывода, который поставляется вместе с опцией --verbose CLI.


Как отмечали другие ответы, лучше всего проверить результат, используя встроенные методы, например:

$this->expectOutputString('foo');

Однако иногда полезно быть непослушным и видеть одноразовый/временный отладочный вывод из ваших тестовых случаев. Тем не менее, нет необходимости в var_dump хаке/обходном пути. Это можно легко выполнить, установив параметр командной строки --verbose при запуске набора тестов. Например:

$ phpunit --verbose -c phpunit.xml

Это отображает результат внутри ваших тестовых методов при работе в среде CLI.

Ответ 2

Обновление: Смотрите rdlowrey update ниже относительно использования fwrite(STDERR, print_r($myDebugVar, TRUE)); как более простой работы


Это поведение является намеренным (поскольку jasonbar имеет указано), Конфликтное состояние руководства было сообщено на PHPUnit.

Обход должен состоять в том, чтобы PHPUnit утверждал, что ожидаемый вывод пуст (когда на нем имеется выход), который вызовет неожиданный вывод, который будет показан.

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);
    }   
}

дает:

PHPUnit @[email protected] 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.

Обязательно отключите любые другие утверждения, которые у вас есть для теста, поскольку они могут выйти из строя до того, как будет проверено выходное утверждение (и, следовательно, вы не увидите вывод).

Ответ 3

Попробуйте использовать --debug

Полезно, если вы пытаетесь получить правильный путь к файлу данных include или source.

Ответ 4

Это не ошибка, но очень преднамеренная. Лучше всего писать в файл журнала, а хвост - журнал для просмотра вывода.

Если вы пытаетесь выполнить вывод TEST, проверьте этот вне.

также:

Примечание. Обратите внимание, что PHPUnit проглатывает весь вывод, который испускается во время выполнения теста. В строгом режиме - тест, который испускает выход не будет выполнен.

Ответ 5

Мне повезло с VisualPHPUnit, и он помогает показать вывод, среди прочего.

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

TestHello results

Ответ 6

Вы действительно должны думать о своих намерениях: если вам нужна информация сейчас, когда вы отлаживаете, чтобы исправить тест, вам понадобится его на следующей неделе, когда тесты сломаются.

Это означает, что вам понадобится информация всегда, когда тест не удастся - и добавление var_dump, чтобы найти причину, - это слишком большая работа. Скорее помещаем данные в ваши утверждения.

Если ваш код слишком сложный для этого, разделите его, пока не достигнете уровня, на котором одно утверждение (с настраиваемым сообщением) сообщает вам достаточно, чтобы узнать, где он сломался, почему и как исправить код.

Ответ 7

В некоторых случаях можно использовать что-то подобное для вывода чего-либо на консоль

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();
    }
}

Ответ 8

В laravel 5 вы можете использовать dump(), Dump содержание из последнего ответа.

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

дает

Ответ 9

Это было взято из https://phpunit.de/manual/current/en/fixtures.html

Это должно позволить вам сбрасывать информацию в любой момент, задерживая жизненный цикл теста phpunit.

Просто замените __METHOD__ в коде ниже тем, что вы хотите вывести

Пример 4.2: Пример, показывающий все доступные доступные методы шаблонов

<?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;
    }
}
?>

Ответ 10

Я выводил свои тестовые результаты на основе HTML, в этом случае было полезно очистить содержимое:

var_dump($array);
ob_flush();

Существует второй метод PHP

flush() 

который я не пробовал.

Ответ 11

Мне пришлось изменить исходный код, чтобы этот код работал, поэтому вам нужно добавить URL для этот разветвленный репозиторий для композитора для этого будет работать

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);
    }
}