How to output in CLI during execution of PHP Unit tests?

When running a PHPUnit test, I would like to be able to dump output so I can debug one or two things.

I have tried the following (similar to the PHPUnit Manual example);

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

With the following result:

PHPUnit @package_version@ by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 3.00Mb

OK (1 test, 0 assertions)

Notice there is none of the expected output.

I'm using the HEAD versions of the git repos as of September 19th, 2011.

Output of 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

Is there anything I'm doing wrong, or is this potentially a PHPUnit bug?


UPDATE

Just realized another way to do this that works much better than the --verbose command line option:

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

This lets you dump anything to your console at any time without all the unwanted output that comes along with the --verbose CLI option.


As other answers have noted, it's best to test output using the built-in methods like:

$this->expectOutputString('foo');

However, sometimes it's helpful to be naughty and see one-off/temporary debugging output from within your test cases. There is no need for the var_dump hack/workaround, though. This can easily be accomplished by setting the --verbose command line option when running your test suite. For example:

$ phpunit --verbose -c phpunit.xml

This will display output from inside your test methods when running in the CLI environment.

See: Writing Tests for PHPUnit - Testing Output.


Update: See rdlowrey's update below regarding the use of fwrite(STDERR, print_r($myDebugVar, TRUE)); as a much simpler work around


This behaviour is intentional (as jasonbar has pointed out). The conflicting state of the manual has been reported to PHPUnit.

A work-around is to have PHPUnit assert the expected output is empty (when infact there is output) which will trigger the unexpected output to be shown.

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

gives:

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.

Be certain to disable any other assertions you have for the test as they may fail before the output assertion is tested (and hence you wont see the output).


Try using --debug

Useful if you're trying to get the right path to an include or source data file.


It's not a bug, but very much intentional. Your best bet is to write to a log file of some kind and tail the log to watch for output.

If you are trying to TEST output, check this out.

Also:

Note: Please note that PHPUnit swallows all output that is emitted during the execution of a test. In strict mode, a test that emits output will fail.


You should really think about your intentions: If you need the information now when debugging to fix the test, you will need it next week again when the tests break.

This means that you will need the information always when the test fails - and adding a var_dump to find the cause is just too much work. Rather put the data into your assertions.

If your code is too complex for that, split it up until you reach a level where one assertion (with a custom message) tells you enough to know where it broke, why and how to fix the code.