Phpunit: assertEquals doesn't show diff for strings

Created on 27 May 2014  路  10Comments  路  Source: sebastianbergmann/phpunit

PHPUnit 4.1.1, Comparator 1.0.0.

assertEquals('foo', 'bar') outputs only

PHPUnit_Framework_ExpectationFailedException : Failed asserting that two strings are equal.

And there is no info about what strings are not equal.

It seems that here instead of

trim($description . "\n" . $f->getMessage()),

should be

trim($description . "\n" . $f->toString()),

And in this case output will be:

PHPUnit_Framework_ExpectationFailedException : Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'foo'
+'bar'

Most helpful comment

Okay, for the benefit of anyone else who stumbles onto this after me, I just discovered that these two things do NOT result in the same outcome:

A:

try {
    $actual = somePotentiallyExceptionThrowingFunc();
    $this->assertEquals($expected, $actual);
} catch (Exception $e) {
    $this->fail($e->getMessage());
}

And, B:

$actual = null;

try {
    $actual = somePotentiallyExceptionThrowingFunc();
} catch (Exception $e) {
    $this->fail($e->getMessage());
}

$this->assertEquals($expected, $actual);

When the assertion is inside the try block, you only get the one line, Failed asserting that two strings are equal. When the assertion is outside the try block, you get that line, plus the expected/actual diff.

I suppose the catch is over-broad and eating the PHPUnit_Framework_ExpectationFailedException that the assertion is throwing? I can catch that in my tests and re-throw it, but this certainly caught me by surprise.

Hopefully this helps someone else who made the same mistake I did.

All 10 comments

Would have to ask @sebastianbergmann, but this might actually be intentional. In any event, you should be able to do:

try {
    assertEquals('foo', 'bar');
} 

catch (PHPUnit_Framework_ExpectationFailedException $e) {
    echo $e->getComparisonFailure()->toString();
}

Or if you just need the diff:

echo $e->getComparisonFailure()->getDiff();

@whatthejeff, your solution sounds like a functional regression in comparison with older versions of PHPUnit, which shows useful info by default without any catches.

If it's a regression, then I agree it should be fixed.

For single-line strings I do not see value in showing a multi-line diff. IIRC, this has always been the case.

I just tested 3.7 and I don't see a diff. @mekras, which version had diffs?

Closing as this seems to be the intended behavior.

I know things have been this way for a long time, now, but it would still be useful to see what the expected and actual values were, otherwise you end up resorting to having to temporarily instrument your tests with var_dump()s to see what the actual value was, which is tedious and annoying.

FWIW, the latest documentation for PHPUnit 6.4.0 still suggests that seeing the actual and expected values in the test runner output is the expected behavior:

https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertEquals

Okay, for the benefit of anyone else who stumbles onto this after me, I just discovered that these two things do NOT result in the same outcome:

A:

try {
    $actual = somePotentiallyExceptionThrowingFunc();
    $this->assertEquals($expected, $actual);
} catch (Exception $e) {
    $this->fail($e->getMessage());
}

And, B:

$actual = null;

try {
    $actual = somePotentiallyExceptionThrowingFunc();
} catch (Exception $e) {
    $this->fail($e->getMessage());
}

$this->assertEquals($expected, $actual);

When the assertion is inside the try block, you only get the one line, Failed asserting that two strings are equal. When the assertion is outside the try block, you get that line, plus the expected/actual diff.

I suppose the catch is over-broad and eating the PHPUnit_Framework_ExpectationFailedException that the assertion is throwing? I can catch that in my tests and re-throw it, but this certainly caught me by surprise.

Hopefully this helps someone else who made the same mistake I did.

Was this page helpful?
0 / 5 - 0 ratings