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

Make TestCase methods final that should have been final all along #5254

Closed
sebastianbergmann opened this issue Feb 24, 2023 · 10 comments
Closed
Assignees
Labels
type/backward-compatibility Something will be/is intentionally broken
Milestone

Comments

@sebastianbergmann
Copy link
Owner

  • runTest()
  • iniSet()
  • setLocale()
  • createStub()
  • createStubForIntersectionOfInterfaces()
  • createMock()
  • createMockForIntersectionOfInterfaces()
  • createConfiguredMock()
  • createPartialMock()
  • createTestProxy()
  • getMockForAbstractClass()
  • getMockFromWsdl()
  • getMockForTrait()
  • getObjectForTrait()
@sebastianbergmann sebastianbergmann added the type/backward-compatibility Something will be/is intentionally broken label Feb 24, 2023
@sebastianbergmann sebastianbergmann added this to the PHPUnit 11.0 milestone Feb 24, 2023
@sebastianbergmann sebastianbergmann self-assigned this Feb 24, 2023
@sebastianbergmann sebastianbergmann changed the title Make TestCase methods final that should have been final all along Make TestCase methods final that should have been final all along Mar 6, 2023
@driesvints
Copy link

I'm begging you not to do this. Laravel very much relies on these methods, especially runTest which handles so much of the internal exception throwing: https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L168

@sebastianbergmann
Copy link
Owner Author

I'm begging you not to do this. Laravel very much relies on these methods, especially runTest which handles so much of the internal exception throwing: https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L168

Allowing to override runTest() is just "too much". But I am sure that what you need can be accomplished in another way, even if that way is not implemented yet.

Can you explain why you currently override runTest()? If that is a use case worth supporting, than I am open to implementing a specific API for it.

@driesvints
Copy link

Thank you for considering it! For Laravel's HTTP testing we check if there's a latest response:

https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L175

If that's the case we'll transform the exception to provide more info depending on what type of response it is:

https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Testing/TestResponse.php#L1566-L1593

@sebastianbergmann
Copy link
Owner Author

sebastianbergmann commented Apr 3, 2023

Would this help?

WIP: Implement TestCase::transformException() hook method (main branch)

diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php
index b875580d5..00898d070 100644
--- a/src/Framework/TestCase.php
+++ b/src/Framework/TestCase.php
@@ -671,7 +671,7 @@ final public function runBare(): void
                     null
                 );
             } else {
-                $e = $_e;
+                $e = $this->transformException($_e);
 
                 $this->status = TestStatus::error($e->getMessage());
 
@@ -1465,6 +1465,11 @@ protected function getObjectForTrait(string $traitName, array $arguments = [], s
         );
     }
 
+    protected function transformException(Throwable $t): Throwable
+    {
+        return $t;
+    }

Test.php

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class OriginalException extends RuntimeException
{
}

final class ModifiedException extends RuntimeException
{
}

final class Test extends TestCase
{
    public function testOne(): void
    {
        throw new OriginalException('original message');
    }

    protected function transformException(Throwable $t): Throwable
    {
        return new ModifiedException('modified message');
    }
}
PHPUnit 10.1-dev by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.4

E                                                                   1 / 1 (100%)

Time: 00:00.019, Memory: 4.00 MB

There was 1 error:

1) Test::testOne
ModifiedException: modified message

/home/sb/Test.php:21

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

@crynobone
Copy link

crynobone commented Apr 3, 2023

@sebastianbergmann yes that would be useful. Previously we used onNotSuccessfulTest but it no longer exists in PHPUnit 10 and the reason why we need to override runTest() at the moment.

https://github.com/laravel/framework/blob/d68fefe71e5c670cc3d83d9df8ad3b40ed123dac/src/Illuminate/Foundation/Testing/TestCase.php#L295-L308

@driesvints
Copy link

@sebastianbergmann yes that would solve this! Thank you 🙂

@sebastianbergmann
Copy link
Owner Author

Previously we used onNotSuccessfulTest but it no longer exists in PHPUnit 10 and the reason why we need to override runTest() at the moment.

onNotSuccessfulTest() still exists, but can no longer be (ab)used for this.

@taylorotwell
Copy link

Reconsider? If your concern with these not being final is people's application's breaking if they override them, create a GitHub saved reply explaining you override those methods at your own risk and any breakages from doing so are not your problem and close the issue?

@bram-pkg
Copy link

#[Override]
protected function runTest(): mixed
{
    // CI systems like GitHub Actions set the CI environment variable
    if (getenv('CI')) {
        return retry(3, function () {
            return parent::runTest();
        });
    }

    return parent::runTest();
}

We were using runTest() to provide automatic "retry" functionality to flaky tests while we attempt to fix them.

Do you have any suggestions on what we can override now to have this behaviour? I have dug into the source code of PHPUnit 11 and have not found any methods to override easily to achieve this.

@roxblnfk
Copy link

roxblnfk commented Sep 18, 2024

I also use runTest() in many projects. It seems I'll have to stay on 10.x forever.
Hope this version will support PHP 9 😄
But the best solution would be adding interceptors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/backward-compatibility Something will be/is intentionally broken
Projects
None yet
Development

No branches or pull requests

6 participants