Problem/Motivation
In #2571475: Outbound HTTP requests fail with KernelTestBase we added a test without an assertion. PHPunit usually fails if a test does not assert anything, but because KernelTestBaseTest::tearDown() performs an assertion, all KernelTestBaseTests are considered to assert something.
Steps to reproduce
Proposed resolution
Refactor KernelTestBaseTest::tearDown() so it does not perform an assertion but still fails if the teardown conditions are not met.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | 3196507-9.patch | 1.04 KB | longwave |
| #7 | run_isolated_disables_strict.png | 86.52 KB | mxr576 |
| #2 | 3196507.patch | 799 bytes | longwave |
Issue fork drupal-3196507
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3196507-kerneltestbasetestteardown-should-not
changes, plain diff MR !9122
Comments
Comment #2
longwaveComment #3
mxr576Thanks for opening this follow up, LGTM.
Comment #4
longwaveWhy didn't this fail while #3196470: KernelTestBaseTest::testOutboundHttpRequest() does not perform any assertion is still open?
Comment #5
mxr576hm, indeed, that is odd
beStrictAboutTestsThatDoNotTestAnything="true", my gut says something else also performs an assert.Comment #6
mxr576Okay, so the following happens, if I remove ALL test methods before
testOutboundHttpRequest()then the error is triggered, if at least one test method runs beforetestOutboundHttpRequest()then PHPUnit does not warn about the missing assert intestOutboundHttpRequest().Comment #7
mxr576Just as I thought, the fact that this test runs in a separate process causes the problem. Before the test starts, PHPUnit disables the strict mode, bug?No, that is not true, I am not sure why I saw this result, but since then I realised
\Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::startTest()gets called and because\Symfony\Bridge\PhpUnit\ExpectDeprecationTraitis implemented by KernelTestBase (which extended by its own test), it disables thebeStrictAboutTestsThatDoNotTestAnything():(Comment #8
mxr576The commit which added the problematic line to upstream: https://github.com/symfony/phpunit-bridge/commit/82c0ff21da6ace856ac3494...
and the ExceptionDeprecationTrait was added in Since symfony/phpunit-bridge 5.1: Using "@expectedDeprecation" annotations in tests is deprecated, use the "ExpectDeprecationTrait::expectDeprecation()" method instead.
This seems a side-effect of this change.
Comment #9
longwaveIs that because expected deprecations are counted as assertions, but if a test only expects deprecations and doesn't assert anything else, if beStrictAboutTestsThatDoNotTestAnything is set then PHPUnit will fail early? The bridge class does its own checks using the checkNumAssertions flag to apparently work around this in some cases.
We can add an explicit extra test, which helps I guess, but doesn't stop us adding other tests that don't assert anything.
Comment #10
mondrakeWe might also throw a \RuntimeException instead, but it does not really matter. RTBC
Comment #11
alexpottThe test only fails when it is run by itself?!?!
Comment #12
alexpottThis is a problem with Symfony code. We need to implement proper logic if a test returns true for $test->doesNotPerformAssertions() and cause it to fail.
Comment #13
alexpottHere's a PR to address this in symfony - https://github.com/symfony/symfony/pull/40957
Comment #15
longwaveWe are now using a version of symfony/phpunit-bridge that includes the fix in #13 but I still get the same result in #11 when running the single test vs running the entire class?
Comment #20
mondrakeMaybe time to try again in PHPUnit 10.
Comment #22
mondrakePostponed on #3466788: Fix ‘risky’ tests
Comment #23
mondrakeBlocker is in.
Comment #24
mondrakeComment #25
smustgrave commentedRefactor seems fine, accomplishes the task without breaking anything
Comment #26
longwaveIs it not simpler just to do this to explicitly test the
tearDown()method, and avoid this code running on all other teardowns in this class?Maybe I could have thought of this three years ago :)
Comment #27
mondrakeUhm we shouldn’t call tearDown() from a test directly IMHO. The tear down process involves the framework calling methods marked with
PostConditionandAfterattributes - tearDown is just ‘one’ of such methods nowadays.Comment #29
longwaveFair enough. Let's get this in.
Committed d38aac1 and pushed to 11.x. Thanks!