Phpunit: Prohibit using PHPUnit with unsupported versions of PHP

Created on 28 Aug 2019  路  8Comments  路  Source: sebastianbergmann/phpunit

People are trying to use PHPUnit 7 with PHP 7.4, for instance, and Composer does not prevent them from doing so due to "php": "^7.1" in composer.json. Similarly, phpunit.phar has no measure for preventing it from being used with PHP versions that are too new. Both mechanisms, Composer and PHAR, of course ensure that PHPUnit is not used with versions of PHPUnit that are too old.

@Ocramius, for instance, is considering similar measures for his projects, see https://github.com/Ocramius/ProxyManager/issues/492 for reference.

typenhancement

Most helpful comment

Please do not enforce a maximum version of PHP on startup. That doesn't help anyone, but adds more annoyance on top of --ignore-platform-reqs.

All 8 comments

Note: this is super-annoying when people are working on bleeding edge, but --ignore-platform-reqs works for trying out bleeding edge.

PHPUnit 9 will support PHP 7.3, PHP 7.4, and PHP 8.0. Starting with that version, we will enforce the PHP version supported by PHPUnit.

For Composer this is easy:

--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,7 @@
     },
     "prefer-stable": true,
     "require": {
-        "php": "^7.2",
+        "php": "7.3.* || 7.4.* || 8.0.*",
         "ext-dom": "*",
         "ext-json": "*",
         "ext-libxml": "*",
@@ -52,7 +52,7 @@
     },
     "config": {
         "platform": {
-            "php": "7.2.0"
+            "php": "7.3.0"
         },
         "optimize-autoloader": true,
         "sort-packages": true

As @Ocramius already commented, --ignore-platform-reqs can be used to override this.

However, I would also like to enforce the maximum supported version of PHP on startup, just like we already do for the minimum required version of PHP. Simply doing

--- a/phpunit
+++ b/phpunit
@@ -9,11 +9,11 @@
  * file that was distributed with this source code.
  */

-if (version_compare('7.2.0', PHP_VERSION, '>')) {
+if (!in_array(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, ['7.3', '7.4', '8.0'])) {
     fwrite(
         STDERR,
         sprintf(
-            'This version of PHPUnit is supported on PHP 7.2, PHP 7.3, and PHP 7.4.' . PHP_EOL .
+            'This version of PHPUnit is supported on PHP 7.3, PHP 7.4, and PHP 8.0.' . PHP_EOL .
             'You are using PHP %s (%s).' . PHP_EOL,
             PHP_VERSION,
             PHP_BINARY

would render the aforementioned -ignore-platform-reqs pointless. I therefore propose the introduction of an environment variable, PHPUNIT_IGNORE_PHP_VERSION, to ignore the required/supported PHP version:

--- a/phpunit
+++ b/phpunit
@@ -9,11 +9,12 @@
  * file that was distributed with this source code.
  */

-if (version_compare('7.2.0', PHP_VERSION, '>')) {
+if (!isset($_ENV['PHPUNIT_IGNORE_PHP_VERSION']) &&
+    !in_array(PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, ['7.3', '7.4', '8.0'])) {
     fwrite(
         STDERR,
         sprintf(
-            'This version of PHPUnit is supported on PHP 7.2, PHP 7.3, and PHP 7.4.' . PHP_EOL .
+            'This version of PHPUnit is supported on PHP 7.3, PHP 7.4, and PHP 8.0.' . PHP_EOL .
             'You are using PHP %s (%s).' . PHP_EOL,
             PHP_VERSION,
             PHP_BINARY

This approach also allows PHPUnit itself to be tested against "bleeding edge" PHP versions.

Please do not enforce a maximum version of PHP on startup. That doesn't help anyone, but adds more annoyance on top of --ignore-platform-reqs.

That is indeed annoying, but it is also true that folks running on bleeding edge can set PHPUNIT_IGNORE_PHP_VERSION in their .env or environment variables in CI if they really must.

Just throwing it out: Add 8.0-dev as a supported version for PHPUnit 8 (and in the future, whatever PHP versions are in development at the time of PHPUnit release). That a) allows testing the bleeding edge without hassle, b) shows that PHPUnit does work with it in its current state and c) does not create any long-term support commitments.

The problem right now is that there's a fairly large lag between work on a new PHP version starting and PHPUnit releasing an officially compatible version -- in good conscience, PHPUnit can only really do that very late in the release cycle, because there might still be breaking changes otherwise. PHP 8 is the first time this really shows up due to the way constraints were written, but this is going to be a larger problem with the suggested change to use strict version ranges. We want to encourage people to test nightly on Travis, but right now this is more complicated than it needs to be, because you need to conditionally add --ignore-platform-reqs to your composer invocation (you can't add it when running on older versions), and now also add an extra environment variable.

Allowing the next -dev version seems like a good way to get the best of both worlds here.

Just to clarify: PHPUnit 8 does not have, and will not get, a check that enforces the maximum supported version (which is PHP 7.4).

I have no problem with X.Y-dev for PHP in master thus allowing the "bleeding edge" of PHPUnit to be used with development snapshots of the next PHP version. What I do have a problem with is allowing development snapshots of the next PHP version in stable releases of PHPUnit as there is no way for me to guarantee that such a stable release of PHPUnit will be compatible with the next version of PHP when that becomes stable itself.

Would this be good enough for you, @nikic?

@sebastianbergmann Possibly, I'm not sure how that would look like in practice. Would you have to include || 9.0@dev in composer.json and then maybe additionally specify "prefer-stable": true to avoid it getting picked up unless strictly necessary due to the platform constraint?

What I do have a problem with is allowing development snapshots of the next PHP version in stable releases of PHPUnit as there is no way for me to guarantee that such a stable release of PHPUnit will be compatible with the next version of PHP when that becomes stable itself.

The point of allowing the development snapshot of PHP in the stable release is specifically that the release will not be compatible with the next PHP version when it becomes stable. It allows tiding over CI testing until a PHPUnit version with full support is released, but the new stable PHP version is explicitly not going to be supported on the old PHPUnit version, and composer will force you to use the new PHPUnit version once that time rolls around. At least that's what I had in mind.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kunjalpopat picture kunjalpopat  路  4Comments

sebastianbergmann picture sebastianbergmann  路  4Comments

keradus picture keradus  路  3Comments

AnmSaiful picture AnmSaiful  路  4Comments

nicklevett picture nicklevett  路  4Comments