Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test results cannot be serialized if closures appear in exception traces #2713

Closed
bartfeenstra opened this issue Jun 20, 2017 · 4 comments
Closed

Comments

@bartfeenstra
Copy link

Q A
PHPUnit version 5.y.z/6.y.z
PHP version any

Asserts are not currently allowed to be closures, because when they fail, their calls become part of the failure's backtrace. The failure is stored in the test result, which is serialized.

The specific reason we are using closure asserts, is that some of our asserts are higher-order, and take callables to perform some caller-specific asserts after the higher-order assert is done. These callables are one-off, so it makes little sense to put them in their own named (and needlessly reusable) functions.

Since some parts of the code are 8-9 years old, I assume that closures aren't unsupported here on purpose, but that this is merely a legacy limitation. Unfortunately, I'm not familiar enough with PHPUnit's internals to propose a concrete solution at this point. I'd love to hear other developers' opinions on this :)

@fetmo
Copy link
Contributor

fetmo commented Oct 13, 2017

@bartfeenstra Could you give me some example implementation?

But from your presentation it seems to be the same issue described in #2739.
@sebastianbergmann Do you confirm?

@bartfeenstra
Copy link
Author

I have encountered #2739 in the past, but this is a different issue. A relatively quick way to reproduce this should be to create a test case that's run in isolation, and put the following in a test method:

$closure = function() {
  $this->assertTrue(false);
}
$closure();

This is because ComparisonFailure includes the full internal backtrace, including this closure.

@sebastianbergmann
Copy link
Owner

I am not sure that I follow:

<?php
class Test extends PHPUnit\Framework\TestCase
{
    public function testOne()
    {
        $closure = function() {
            $this->assertTrue(false);
        };

        $closure();
    }
}
$ phpunit --process-isolation Test
PHPUnit 6.4.1 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 73 ms, Memory: 4.00MB

There was 1 failure:

1) Test::testOne
Failed asserting that false is true.

/home/sb/Test.php:7
/home/sb/Test.php:10

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

As you linked to this template, I assume that you use process isolation (which uses serialization for passing data between processes).

However, as you can see above, I do not see an issue with regard to the serialization of the closure that invokes the assertion.

@sebastianbergmann sebastianbergmann added the status/waiting-for-feedback Waiting for feedback from original reporter label Oct 13, 2017
@sebastianbergmann
Copy link
Owner

No feedback, closing.

@sebastianbergmann sebastianbergmann removed the status/waiting-for-feedback Waiting for feedback from original reporter label Nov 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants