When trying to run PHPUnit tests on the MongoDB contrib module for the soon-ready 8.2.0 version, I recently starting encountering this error:
PHPUnit testing framework version 6 or greater is required when running on PHP 7.0 or greater.
Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.
OK, no big deal, let's just run that command.
# From $PROJECT/web/core directory
$ ../../vendor/bin/composer run-script drupal-phpunit-upgrade
In RunScriptCommand.php line 89:
Script "drupal-phpunit-upgrade" is not defined in this package
run-script [--timeout TIMEOUT] [--dev] [--no-dev] [-l|--list] [--]  ...
Hmm, so I need that command but it is not defined in
composer.json. So where is it ?
$ cd $PROJECT
grep -ir drupal-phpunit-upgrade .
./web/core/tests/bootstrap.php: $message = "PHPUnit testing framework version 6 or greater is required when running on PHP 7.0 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.";
./web/core/tests/README.md:- If you're running PHP 7.0 or greater you will need to upgrade PHPUnit with `composer run-script drupal-phpunit-upgrade`
./web/core/scripts/run-tests.sh: simpletest_script_print_error("PHPUnit testing framework version 6 or greater is required when running on PHP 7.0 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
./web/core/scripts/run-tests.sh: passthru("$composer run-script drupal-phpunit-upgrade-check");
./web/core/lib/Drupal/Core/Composer/Composer.php: * Fires the drupal-phpunit-upgrade script event if necessary.
./web/core/lib/Drupal/Core/Composer/Composer.php: // call the drupal-phpunit-upgrade script to upgrade PHPUnit.
So that command is referenced in multiple places, but defined nowhere. What's going on ?
Most of the time, when building Drupal 8 projects, we want to use the drupal-project package, to get a saner project layout. But when contributing to core, the common practice has long been to use either
drupal/drupal or even just a Git checkout of Drupal itself. Things are likely to change on that front when issue #2982674 is fixed, though.
At the same time, PHP versions continue moving, with the now-current version being PHP 7.1.x for most cases, and PHP 7.2.x the target version for this autumn. And PHPunit 4.x, which served us faithfully for years, is not compatible at all with PHP 7.2, so the migration to PHPunit 6.x has been required since Issue #2927806 in april 2018. And is now used for 7.0.x/7.1.x too as detailed in https://www.drupal.org/node/2957906.
But on the other hand,
composer-project/drupal-project provides a
composer.json script which does not include the
drupal-phpunit-upgrade, arguably because it still generates a Drupal 8.5.x version these days, which causes this command to fail.
The expected non-working fix
"drupal-phpunit-upgrade": "@composer update phpunit/phpunit --with-dependencies --no-progress",
Let's just add it to
composer.json and check PHPunit: still version 4.8.x ! The problem is that
composer-project adds a phpunit dependency to 4.8.36, which installed and locked earlier versions, for which Composer cannot find an update path.
The actual fix
Actually, projects do no longer need this line, because of the
webflo/drupal-core-require-dev dependency, which itself requires
phpunit/phpunit (^4.8.35 || ^6.5), which would allow PHPunit 6.x, unlike what our base
composer.json requires. So let's just remove the direct dependency on PHPunit currently locking us to 4.8.
$ composer remove --dev phpunit/phpunit
# ...lots of lines showing the upgrade...
$ vendor/bin/phpunit --version
PHPUnit 6.5.9-3-g2d53bd5ae by Sebastian Bergmann and contributors.
$ composer why phpunit/phpunit
webflo/drupal-core-require-dev 8.6.x-dev requires phpunit/phpunit (^4.8.35 || ^6.5)
As these results show, we now have a PHPunit 6.x, thanks to webflo's package. Problem solved.