-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Deprecate expect*() methods that have been removed in PHPUnit 10 #5062
Comments
Just wondering where I can find information on what this will be replaced with ? |
There are no replacements. PHPUnit 10 no longer converts |
The situation is quite confusing right now since version 9.5's |
@jrfnl I changed my test code like this:
|
@thbley Thanks. I think it's good to have such an example in this thread. |
Add a forgotten expectation and remove one test. With phpunit 10 you can't expect PHP errors anymore (sebastianbergmann/phpunit#5062). But that's OK, the test wasn't very valuable.
@sebastianbergmann what is the recommended way of testing that an error is triggered in PHPUnit 10? If you want to assert that an E_USER_WARNING is thrown by your code what is the best way to do this? Should you replace the error handler as above or is there a better way? |
Add a forgotten expectation and remove one test. With phpunit 10 you can't expect PHP errors anymore (sebastianbergmann/phpunit#5062). But that's OK, the test wasn't very valuable.
…ann/phpunit#5062 issue. And also, some changes for warning of code structure
I just want to comment on the proposed solution above: restore_error_handler(); is never executed because the exception gets thrown before it. public function test_foo() {
set_error_handler(
static function ( $errno, $errstr ) {
restore_error_handler();
throw new Exception( $errstr, $errno );
},
E_ALL
);
$this->expectException( Exception::class );
$this->expectExceptionMessageMatches( 'Expected message' );
// run some code that produces E_USER_WARNING
} |
In my case, I did this :
and then, in each test :
|
@BafS You can find an explanation about the why in the Release announcement: https://phpunit.de/announcements/phpunit-10.html |
@jrfnl thank for the link, great to have something official, I didn't see it mentioned before |
I don't understand why he is uncharacteristically mute and unresponsive to suddenly unplugging a widely used method with neither explanation nor an alternative. If I'm expecting a warning, odds are that that is the subject of the test. The example in the version 10 release notes show further assertion that |
This is a use case that I do not consider worth supporting. I understand that this is frustrating, and I am sorry for that. |
I guess in my case, the deliberate warning can be relocated to a mockable method. It's a workaround like trying to test register shutdown function. In this case, however, I'm not sure it's possible for all object types and SUTs |
Remove the `ExpectPHPException` polyfill and all references to it as support for expecting PHP native and user added deprecations, notices, warnings and errors has been dropped in PHPUnit 10.0. PHP native Exceptions can still be tested using the `expectException()` method with the name of the PHP native Exception. Refs: * https://phpunit.de/announcements/phpunit-10.html * https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-10.0.md#1000---2023-02-03 * sebastianbergmann/phpunit#3775 * sebastianbergmann/phpunit#5062 * sebastianbergmann/phpunit@a2c784c
Remove the `ExpectPHPException` polyfill and all references to it as support for expecting PHP native and user added deprecations, notices, warnings and errors has been dropped in PHPUnit 10.0. PHP native Exceptions can still be tested using the `expectException()` method with the name of the PHP native Exception. Refs: * https://phpunit.de/announcements/phpunit-10.html * https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-10.0.md#1000---2023-02-03 * sebastianbergmann/phpunit#3775 * sebastianbergmann/phpunit#5062 * sebastianbergmann/phpunit@a2c784c
Remove the `ExpectPHPException` polyfill and all references to it as support for expecting PHP native and user added deprecations, notices, warnings and errors has been dropped in PHPUnit 10.0. PHP native Exceptions can still be tested using the `expectException()` method with the name of the PHP native Exception. Refs: * https://phpunit.de/announcements/phpunit-10.html * https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-10.0.md#1000---2023-02-03 * sebastianbergmann/phpunit#3775 * sebastianbergmann/phpunit#5062 * sebastianbergmann/phpunit@a2c784c
Remove the `ExpectPHPException` polyfill and all references to it as support for expecting PHP native and user added deprecations, notices, warnings and errors has been dropped in PHPUnit 10.0. PHP native Exceptions can still be tested using the `expectException()` method with the name of the PHP native Exception. Refs: * https://phpunit.de/announcements/phpunit-10.html * https://github.com/sebastianbergmann/phpunit/blob/main/ChangeLog-10.0.md#1000---2023-02-03 * sebastianbergmann/phpunit#3775 * sebastianbergmann/phpunit#5062 * sebastianbergmann/phpunit@a2c784c
There's, unfortunately, no details on what should be the alternative way of testing these things that we would've tested with expect* methods. |
If you want to keep a similar implementation but also looking for moving on with PHPUnit updates, you can implement this method in your common test class: protected function assertThrowableMessage(
string $message,
callable $callback,
...$args
): void
{
try {
$callback(...$args);
} catch (Throwable $e) {
$this->assertEquals($message, $e->getMessage());
}
} This way you can assert the exception was properly thrown during runtime and don't have to deal with the |
Thank you! |
Just want to add, that for folk who come from google and are using Laravel, you can use the
There is also an optional second parameter which accepts the class name of the throwable that should get thrown and a third with the error message you expect. |
This bumps direct dependencies to current ones: - phpunit: 9.5.x No updates here, there is the 9.6.x series available but a lot of deprecation warnings have been introduced there without any alternative to use. See: - sebastianbergmann/phpunit#5160 - sebastianbergmann/phpunit#5062 - ... While that will be handy to prepare ourselves to PHPUnit 10 in some months... we cannot force everybody to jump to 9.6.x because that will make a lot of tests to start emitting warnings. So we stay with PHPUnit 9.5.x for the life of this branch. - mink-phpwebdriver: 1.2.1 No updates here, just changed the constraint because we cannot advance to 1.3.x yet, there is a change there causing some app tests to fail. See: - oleg-andreyev/MinkPhpWebDriver#81 So we stay with 1.2.x until that issue is fixed/clarified, only then we'll review the status. - behat: 3.12.x => 3.13.x And also, automatically, a bunch of 2nd and deepest dependencies. Generated with php80 that is the lowest php version supported by this branch and, also, by some of the dependencies, as per documented @ https://moodledev.io/general/development/tools/composer Worth mentioning behat/mink-goutte-driver, that we should move to mink-browserkit-driver, but that's out from this issue scope.
This bumps direct dependencies to current ones: - phpunit: 9.5.x No updates here, there is the 9.6.x series available but a lot of deprecation warnings have been introduced there without any alternative to use. See: - sebastianbergmann/phpunit#5160 - sebastianbergmann/phpunit#5062 - ... While that will be handy to prepare ourselves to PHPUnit 10 in some months... we cannot force everybody to jump to 9.6.x because that will make a lot of tests to start emitting warnings. So we stay with PHPUnit 9.5.x for the life of this branch. - mink-phpwebdriver: 1.2.1 No updates here, just changed the constraint because we cannot advance to 1.3.x yet, there is a change there causing some app tests to fail. See: - oleg-andreyev/MinkPhpWebDriver#81 So we stay with 1.2.x until that issue is fixed/clarified, only then we'll review the status. - behat: 3.12.x => 3.13.x And also, automatically, a bunch of 2nd and deepest dependencies. Generated with php80 that is the lowest php version supported by this branch and, also, by some of the dependencies, as per documented @ https://moodledev.io/general/development/tools/composer Worth mentioning behat/mink-goutte-driver, that we should move to mink-browserkit-driver, but that's out from this issue scope.
This bumps direct dependencies to current ones: - phpunit: 9.5.x No updates here, there is the 9.6.x series available but a lot of deprecation warnings have been introduced there without any alternative to use. See: - sebastianbergmann/phpunit#5160 - sebastianbergmann/phpunit#5062 - ... While that will be handy to prepare ourselves to PHPUnit 10 in some months... we cannot force everybody to jump to 9.6.x because that will make a lot of tests to start emitting warnings. So we stay with PHPUnit 9.5.x for the life of this branch. - mink-phpwebdriver: 1.2.1 No updates here, just changed the constraint because we cannot advance to 1.3.x yet, there is a change there causing some app tests to fail. See: - oleg-andreyev/MinkPhpWebDriver#81 So we stay with 1.2.x until that issue is fixed/clarified, only then we'll review the status. - behat: 3.12.x => 3.13.x And also, automatically, a bunch of 2nd and deepest dependencies. Generated with php74 that is the lowest php version supported by this branch and, also, by some of the dependencies, as per documented @ https://moodledev.io/general/development/tools/composer Worth mentioning behat/mink-goutte-driver, that we should move to mink-browserkit-driver, but that's out from this issue scope.
sebastianbergmann/phpunit#5062 Signed-off-by: Vitor Mattos <[email protected]>
sebastianbergmann/phpunit#5062 Signed-off-by: Vitor Mattos <[email protected]>
sebastianbergmann/phpunit#5062 Signed-off-by: Vitor Mattos <[email protected]>
sebastianbergmann/phpunit#5062 Signed-off-by: Vitor Mattos <[email protected]>
sebastianbergmann/phpunit#5062 Signed-off-by: Vitor Mattos <[email protected]>
I always use this approach and don’t have to dance with a tambourine (calling Exception); $check=false;
set_error_handler(funciton(...$args)use(&$check){
// your code
$check=true;
// your code
},E_NOTICE);
// trigger error your code
restore_error_handler();
unset($check):
$this->assertTrue($check); You can write your own solution trait MyAssertionsTrait
{
/**
* Will return TRUE if an observed error was thrown, FALSE if there are generated other errors or no errors , and will throw an error if other errors are observed
* @param\Closure $call Runs a closure with a code that needs to be checked for an error. If the error is an exception, then the variable $this will be defined in the closure. Checking for $this - isset($this)
* @param string|\Closure $eql If a line, then checks whether this substring is present at the beginning of the error message.
* If there is a closure, then the error checking code must be specified in the closure. If the test is successful, the closure should return true.
* @param int|\Error $level
*/
public static function isError($call, $eql, $level = E_ALL): bool
{
$err_level=is_int($level)?$level:E_ALL;
$exc_level=is_string($level)?$level:\Error::class;
if (is_string($eql)) {
$substr = $eql;
$eql = function (...$args) use ($substr) {
if (substr($args[1], 0, strlen($substr)) === $substr) {
return true;
}
return false;
};
}
$check = false;
$bef_hand = null;
$is_caught_error=false;
$bef_hand = set_error_handler(function (...$args) use (&$bef_hand, &$check, $eql,&$is_caught_error) {
$is_caught_error=true;
if (true===$eql(...$args)) {
// Expected error
$check = true;
return true;
} else if ($bef_hand !== null) {
//We pass other errors to the previous error handler
return $bef_hand(...$args);
}
return false;
}, $err_level);
try{
$call();
}catch(\Error $e){
if(!($e instanceof $exc_level)){
throw $e;
}
$eql=$eql->bindTo($e);
$code=$e->getCode();
if(empty($code)){
$code=E_ERROR;
}
if(!$is_caught_error && true===$eql($code,$e->getMessage(),$e->getFile(),$e->getLine())){
$check=true;
}
} finally {
restore_error_handler();
return $check;
}
}
}
$this->assertTrue(self::isError(fn()=>trigger_error('Ops!');,'Ops!',E_USER_NOTICE)); For the beauty of the design code, you can do this use MyAssertionsTrait as Assert;
//....
$this->assertTrue(Assert::isError(....));
//... In any case, you will have to have your own (or shared) repository with assistants to improve testing. In this repository you can collect all the necessary libraries for testing. |
expectDeprecation()
,expectDeprecationMessage()
, andexpectDeprecationMessageMatches()
expectError()
,expectErrorMessage()
, andexpectErrorMessageMatches()
expectNotice()
,expectNoticeMessage()
, andexpectNoticeMessageMatches()
expectWarning()
,expectWarningMessage()
, andexpectWarningMessageMatches()
The text was updated successfully, but these errors were encountered: