4

I'm trying to put together some PHPUnit tests in Drupal 8. I'm running the tests from the command line, using /vendor/bin/phpunit, but I'm having troubles figuring out how to dump a variable to the screen for debugging purposes.

For that matter, I'm using this:

$this->assertEquals(2, $this->currentUser->id(), 'ID is correct');

And when it passes, the message 'ID is correct' is not shown in the console. Does anyone know how to make the error messages properly show?

  • Have you tried var_dump? – ya.teck Nov 26 '16 at 14:30
  • I have, it doesn't work. Apparently newer versions of PHPUnit gobble up any output like that. I do have a sort of solution I'm going to post below though. – Jaypan Nov 26 '16 at 14:33
  • Well, Drupal 8 is bundled with phpunit v4.8 which is pretty old branch. – ya.teck Nov 26 '16 at 14:38
  • I read somewhere it was version 3.something when they started gobbling output. – Jaypan Nov 26 '16 at 14:40
  • var_dump works for me if it is placed before first failure. – ya.teck Nov 26 '16 at 14:45
7

Recent versions of PHPUnit swallow output. To get around this, you need to run with the --debug flag, eg

$ ../vendor/bin/phpunit --debug modules/migrate/tests/src/Unit/process/FormatDateTest.php

Then you can see printed output.

Also note that PHPUnit will skip tests with output in them with the default phpunit.xml file, because it will deem them risky. To avoid this update the beStrictAboutOutputDuringTests="false" setting and your tests will run.

You can also use the $message parameter to output something when an assertion fails.

2

Well, I found a solution that works. I'm not sure if it is the best way to do it, but actually, it its own way it seems like it is probably the way it's supposed to be done.

First, I discovered that while the assertion message is not output for successful assertions, it is output for failures. So you can append your value to the assertion message, to see what it is:

$b = 'some other value';
$this->assertEquals('some value', $b, '$b is not equal to "some value", instead it is instead: ' . $b);

Since 'some value' does not equal 'some other value', the output is:

$b is not equal to "some value" it is instead: some other value

  • This is crazy but seems to be the only thing that works. – Felix Eve Jan 25 '18 at 5:31
2
$this->assertEquals('some arbitrary value', print_r($thing_i_want_to_see, TRUE));

This causes the assertion to fail, and shows you the difference between your 'arbitrary value' and the actual value. You can then read the actual value. Watch out for complex and recursive data structures.

You can also do error_log() and watch your log file, but Drupal functional tests will swallow that. Works great for unit tests, though.

  • You can call assertions statically from anywhere in the code, not just within tests: \PHPUnit\Framework\Assert::assertEquals(FALSE, $thing_i_want_to_see); – joachim Nov 30 '18 at 12:00
1

I've made a rough start on getting Symfony's dump() command to work in tests. There's a patch at https://www.drupal.org/node/2795567, though I'm stuck on how to take it further.

1

It seems almost impossible to make any output appear on the screen. Jaypan's answer does work but is no good if you want to write output from a file that is not extending BrowserTestBase.

dd() also fails to output to /tmp/drupal_debug.txt so I've written my own function:

if(!function_exists('mylog')) {
  function mylog($var, $label = NULL) {

    $tmp_file = '/tmp/my_debug.log';

    $output = '';
    if(!is_null($label)) {
      $output = $label . ': ';
    }

    $output .= print_r($var, 1) . PHP_EOL;

    file_put_contents($tmp_file, $output, FILE_APPEND);
  }
}

I paste this into every file I need to create debug output and then simply tail /tmp/my_debug.log.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.