Problem/Motivation
Similarly to #2950132: Support PHPUnit 7 optionally in Drupal 8, while keeping support for ^6.5, this issue is about enabling testing with PHPUnit 8 in Drupal 8.
PHPUnit 6 is out of support since Feb 1, 2019
PHPUnit 7 will be end of support Feb 7, 2020
PHPUnit 8 will be supported until Feb 5, 2021
PHPUnit 9 will be released Feb 2020.
The big problem with PHPUnit 8 is that it is changing the signature of the main test methods that test classes extend - above all setUp()
and tearDown
.
This means that ALL the 1700+ implementations of setUp()
and the 30 of tearDown()
in Drupal test code will have to be touched one way or another - unless I'm mistaken.
Also, in PHPUnit8 several assertions methods are deprecated for removal in PHPUnit9, for example:
- Using assertContains() with string haystacks is deprecated and will not be supported in PHPUnit 9. Refactor your test to use assertStringContainsString() or assertStringContainsStringIgnoringCase() instead.
- The @expectedException, @expectedExceptionCode, @expectedExceptionMessage, and @expectedExceptionMessageRegExp annotations are deprecated. They will be removed in PHPUnit 9. Refactor your test to use expectException(), expectExceptionCode(), expectExceptionMessage(), or expectExceptionMessageRegExp() instead.
- assertInternalType() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertIsArray(), assertIsBool(), assertIsFloat(), assertIsInt(), assertIsNumeric(), assertIsObject(), assertIsResource(), assertIsString(), assertIsScalar(), assertIsCallable(), or assertIsIterable() instead.
- assertArraySubset() is deprecated and will be removed in PHPUnit 9.
- getObjectAttribute() is deprecated and will be removed in PHPUnit 9.
- readAttribute() is deprecated and will be removed in PHPUnit 9.
Open points
- None at the moment.
Spun off issues
MigrateExecutableMemoryExceededTest
- it has mock expectation fails in PHPUnit8 due to inconsistent matches(). Added a @todo and commented out the failing tests. #3102903: MigrateExecutableMemoryExceededTest has mismatched argument type mock expectations (and fails in PHPUnit8)ViewExecutableTest
- it has mock expectation fails in PHPUnit8 due to callback return type should be bool and not string. Added a @todo and commented out the failing tests. #3102899: ViewExecutableTest uses a mocked argument callback wrongly (and fails in PHPUnit8)- #3094151: ExpectDeprecationTrait is not compatible with PHPUnit 8
- #3097822: Drupal\migrate_drupal\Tests\StubTestTrait is not compatible with PHPUnit 8
Proposed resolution
I can see two options:
1. Change the signatures of the methods in Drupal test code according to PHPUnit 8
This will have the impact of forcing testing only on PHP 7.2+ (the minimum allowed by PHPUnit8), and from the day such a change will be in core, all contrib module will have to comply or fail tests.
2. Introduce a compatibility layer
- A new
Drupal\Tests\BaseTestClass
, extending fromPHPUnit\Framework\TestCase
, is the new base class for ANY Drupal test, being Unit, Kernel, Functional, etc - The
Drupal\Tests\BaseTestClass
is actually aliased to aDrupal\TestTools\PhpUnitCompatibility\PhpUnit#\BaseTestCase
class, one for each PHPUnit version, using the compatibility layer mechanism put in place to support PHPUnit 7. These aliased classes hold the override of the::setUp()
,::tearDown()
, etc methods, type hinted according to the specific PHPUnit version. - Each overridden method calls a corresponding proxy in the test class so
::setUp()
->::xxxSetup()
. The naming tbd. - ALL test classes in Drupal have to rename their PHPUnit overriding methods to the proxies, and any call to
parent::method()
to the parent proxy, too i.e.parent::setUp()
-->parent::xxSetUp()
Remaining tasks
A lot
User interface changes
None
API changes
Some
Data model changes
None
Release notes snippet
TBD