在运行PHPUnit测试时,我希望能够转储输出,以便调试一两个东西。

我已经尝试了以下(类似于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);
    }   
}

结果如下:

PHPUnit @package_version@ by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.00Mb

OK (1 test, 0 assertions)

注意,这里没有预期的输出。

我使用的是2011年9月19日的git回购的HEAD版本。

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错误?


当前回答

PHPUnit用ob_start()隐藏输出。我们可以暂时关闭它。

    public function log($something = null)
    {
        ob_end_clean();
        var_dump($something);
        ob_start();
    }

其他回答

尝试使用——debug

如果您试图获得包含数据文件或源数据文件的正确路径,则此选项非常有用。

我在VisualPHPUnit上有一些运气,它确实有用地显示了输出。

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

可以使用Symfony\Component\Console\Output\TrimmedBufferOutput,然后像这样测试缓冲的输出字符串:

use Symfony\Component\Console\Output\TrimmedBufferOutput;

//...
public function testSomething()
{
   $output = new TrimmedBufferOutput(999);
   $output->writeln('Do something in your code with the output class...');
   
   //test the output:
   $this->assertStringContainsString('expected string...', $output->fetch());   
}

在某些情况下,可以使用类似的东西向控制台输出一些内容

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

更新

刚刚发现了另一种方法,它比——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环境中运行时,这将显示测试方法内部的输出。

参见:为PHPUnit编写测试-测试输出。