From d926eb94241c4073500d14d9689def5b4ec36980 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Nov 2026 22:03:12 +0000 Subject: [PATCH 1/4] Build/Test Tools: Read the installed PHPUnit version from Composer instead of running it in Docker. Composer installs dependencies on the runner with the same PHP version as the container, so the version can be read with `Composer\InstalledVersions` straight after install. This removes a container start from every job. --- .../workflows/reusable-phpunit-tests-v3.yml | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 6cae9a7530568..33191a290f6c6 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -247,6 +247,21 @@ jobs: with: custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") + # The runner's PHP version matches the container's, so the PHPUnit version installed here is the one the tests use. + - name: Select PHPUnit configuration + run: | + PHPUNIT_VERSION=$(php -r 'require "vendor/autoload.php"; echo Composer\InstalledVersions::getVersion("phpunit/phpunit");') + echo "Detected PHPUnit version: ${PHPUNIT_VERSION}" + if [ "$(echo "${PHPUNIT_VERSION}" | cut -d. -f1)" -ge 10 ]; then + if [ "${PHPUNIT_CONFIG}" = "tests/phpunit/multisite.xml" ]; then + NEW_CONFIG="tests/phpunit/multisite10.xml" + else + NEW_CONFIG="phpunit10.xml.dist" + fi + echo "Using PHPUnit 10+ configuration: ${NEW_CONFIG}" + echo "PHPUNIT_CONFIG=${NEW_CONFIG}" >> "$GITHUB_ENV" + fi + - name: Install npm dependencies run: npm ci @@ -293,20 +308,6 @@ jobs: - name: Install WordPress run: npm run env:install - - name: Select PHPUnit configuration - run: | - PHPUNIT_VERSION=$(node ./tools/local-env/scripts/docker.js run php ./vendor/bin/phpunit --version | grep -oE '\b[0-9]+\.[0-9]+' | head -n 1) - echo "Detected PHPUnit version: ${PHPUNIT_VERSION}" - MAJOR_VERSION=$(echo "${PHPUNIT_VERSION}" | cut -d. -f1) - if [ "${MAJOR_VERSION}" -ge 10 ]; then - if [ "${PHPUNIT_CONFIG}" = "tests/phpunit/multisite.xml" ]; then - NEW_CONFIG="tests/phpunit/multisite10.xml" - else - NEW_CONFIG="phpunit10.xml.dist" - fi - echo "Using PHPUnit 10+ configuration: ${NEW_CONFIG}" - echo "PHPUNIT_CONFIG=${NEW_CONFIG}" >> "$GITHUB_ENV" - fi - name: Run external HTTP tests if: ${{ ! inputs.multisite && ! inputs.phpunit-test-groups && ! inputs.coverage-report }} continue-on-error: ${{ inputs.allow-errors }} From b294ed19ec8f309583ad39a1f86d4a3b1a44c888 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Nov 2026 22:05:17 +0000 Subject: [PATCH 2/4] Docs: Clarify which PHPUnit versions each test configuration file supports. --- tests/phpunit/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/README.md b/tests/phpunit/README.md index 9500fe60f551e..02bb817276682 100644 --- a/tests/phpunit/README.md +++ b/tests/phpunit/README.md @@ -8,16 +8,16 @@ For more information, please review the relevant Core Handbook pages: ## Configuration Files -WordPress core maintains separate configuration files to support both PHPUnit 9 and PHPUnit 10.1+: +WordPress core has separate configuration files for PHPUnit 9 and PHPUnit 10: - `phpunit.xml.dist` and `tests/phpunit/multisite.xml`: Used for PHPUnit 9 and earlier. -- `phpunit10.xml.dist` and `tests/phpunit/multisite10.xml`: Used for PHPUnit 10.1 and later. +- `phpunit10.xml.dist` and `tests/phpunit/multisite10.xml`: Used for PHPUnit 10 and later. These use the `` element, so PHPUnit 10.0 is not supported. ### Running Tests Locally When running tests via Composer: -- `composer test`: Runs tests using the default configuration (PHPUnit < 10). -- `composer test10`: Runs tests using `phpunit10.xml.dist` (PHPUnit 10+). +- `composer test`: Runs tests using the default configuration (PHPUnit 9 and earlier). +- `composer test10`: Runs tests using `phpunit10.xml.dist` (PHPUnit 10 and later). When running tests via npm and Docker: - `npm run test:php`: Runs tests using the default configuration. From f0287290a648e0b490a5af69b236f6592cde15c8 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Nov 2026 22:07:04 +0000 Subject: [PATCH 3/4] Build/Test Tools: Remove an unused PHPUnit configuration entry from .gitignore. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 01c9060ac602d..74312255d037c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ wp-tests-config.php .phpunit.result.cache /phpunit.xml /phpunit10.xml -/phpunit-10.xml /.phpcs.xml /phpcs.xml .cache/* From 543638d60a2b90b7bdd9bc3bbad8822e6f96ec11 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Tue, 10 Nov 2026 22:24:41 +0000 Subject: [PATCH 4/4] Build/Test Tools: Pick the PHPUnit configuration file from the installed PHPUnit version. Adds tests/phpunit/phpunit-config.php, which prints the configuration file for the installed version. composer test, npm run test:php and CI use it, which removes the test10 and test:php10 scripts. --- .../workflows/reusable-phpunit-tests-v3.yml | 16 ++---- composer.json | 3 +- package.json | 3 +- tests/phpunit/README.md | 12 ++--- tests/phpunit/phpunit-config.php | 51 +++++++++++++++++++ 5 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 tests/phpunit/phpunit-config.php diff --git a/.github/workflows/reusable-phpunit-tests-v3.yml b/.github/workflows/reusable-phpunit-tests-v3.yml index 33191a290f6c6..882ba5a715c86 100644 --- a/.github/workflows/reusable-phpunit-tests-v3.yml +++ b/.github/workflows/reusable-phpunit-tests-v3.yml @@ -247,20 +247,10 @@ jobs: with: custom-cache-suffix: $(/bin/date -u --date='last Mon' "+%F") - # The runner's PHP version matches the container's, so the PHPUnit version installed here is the one the tests use. + # Release branches run this workflow from trunk, but older branches lack this file. - name: Select PHPUnit configuration - run: | - PHPUNIT_VERSION=$(php -r 'require "vendor/autoload.php"; echo Composer\InstalledVersions::getVersion("phpunit/phpunit");') - echo "Detected PHPUnit version: ${PHPUNIT_VERSION}" - if [ "$(echo "${PHPUNIT_VERSION}" | cut -d. -f1)" -ge 10 ]; then - if [ "${PHPUNIT_CONFIG}" = "tests/phpunit/multisite.xml" ]; then - NEW_CONFIG="tests/phpunit/multisite10.xml" - else - NEW_CONFIG="phpunit10.xml.dist" - fi - echo "Using PHPUnit 10+ configuration: ${NEW_CONFIG}" - echo "PHPUNIT_CONFIG=${NEW_CONFIG}" >> "$GITHUB_ENV" - fi + if: ${{ hashFiles('tests/phpunit/phpunit-config.php') != '' }} + run: echo "PHPUNIT_CONFIG=$(php ./tests/phpunit/phpunit-config.php "${PHPUNIT_CONFIG}")" >> "$GITHUB_ENV" - name: Install npm dependencies run: npm ci diff --git a/composer.json b/composer.json index 1d08656534843..dcb058d3f5c21 100644 --- a/composer.json +++ b/composer.json @@ -81,7 +81,6 @@ "format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source", "lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary,source", "lint:errors": "@lint -n", - "test": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit" ], - "test10": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit -c phpunit10.xml.dist" ] + "test": [ "Composer\\Config::disableProcessTimeout", "@php ./vendor/phpunit/phpunit/phpunit -c \"$(php ./tests/phpunit/phpunit-config.php)\"" ] } } diff --git a/package.json b/package.json index 215a8d3fd3a44..bf0d8340c435d 100644 --- a/package.json +++ b/package.json @@ -148,8 +148,7 @@ "env:logs": "node ./tools/local-env/scripts/docker.js logs", "env:pull": "node ./tools/local-env/scripts/docker.js pull", "test:performance": "wp-scripts test-playwright --config tests/performance/playwright.config.js", - "test:php": "node ./tools/local-env/scripts/docker.js run --rm php ./vendor/bin/phpunit", - "test:php10": "node ./tools/local-env/scripts/docker.js run --rm php ./vendor/bin/phpunit -c phpunit10.xml.dist", + "test:php": "node ./tools/local-env/scripts/docker.js run --rm php composer test --", "test:coverage": "npm run test:php -- --coverage-html ./coverage/html/ --coverage-php ./coverage/php/report.php --coverage-text=./coverage/text/report.txt", "test:e2e": "wp-scripts test-playwright --config tests/e2e/playwright.config.js", "test:visual": "wp-scripts test-playwright --config tests/visual-regression/playwright.config.js", diff --git a/tests/phpunit/README.md b/tests/phpunit/README.md index 02bb817276682..01252d418f15a 100644 --- a/tests/phpunit/README.md +++ b/tests/phpunit/README.md @@ -15,13 +15,13 @@ WordPress core has separate configuration files for PHPUnit 9 and PHPUnit 10: ### Running Tests Locally -When running tests via Composer: -- `composer test`: Runs tests using the default configuration (PHPUnit 9 and earlier). -- `composer test10`: Runs tests using `phpunit10.xml.dist` (PHPUnit 10 and later). +`composer test` and `npm run test:php` use the single site configuration file that matches the installed version of PHPUnit. A local `phpunit.xml` file is used instead if one exists, so base it on the file that matches your version of PHPUnit. -When running tests via npm and Docker: -- `npm run test:php`: Runs tests using the default configuration. -- `npm run test:php10`: Runs tests using `phpunit10.xml.dist`. +`tests/phpunit/phpunit-config.php` prints the matching configuration file. Pass it either configuration file name to get the one for the installed version, for example to run the multisite tests: + +``` +./vendor/bin/phpunit -c "$(php tests/phpunit/phpunit-config.php tests/phpunit/multisite.xml)" +``` ## Run the full matrix on a pull request diff --git a/tests/phpunit/phpunit-config.php b/tests/phpunit/phpunit-config.php new file mode 100644 index 0000000000000..3b2a16ee970a8 --- /dev/null +++ b/tests/phpunit/phpunit-config.php @@ -0,0 +1,51 @@ +=' ); + +$swaps = array( + 'phpunit.xml.dist' => 'phpunit10.xml.dist', + 'tests/phpunit/multisite.xml' => 'tests/phpunit/multisite10.xml', +); + +if ( ! $is_phpunit_10 ) { + $swaps = array_flip( $swaps ); +} + +if ( ! isset( $argv[1] ) ) { + if ( file_exists( $root . '/phpunit.xml' ) ) { + echo 'phpunit.xml'; + } else { + echo $is_phpunit_10 ? 'phpunit10.xml.dist' : 'phpunit.xml.dist'; + } + exit; +} + +$config = $argv[1]; +$real = realpath( $config ); + +foreach ( $swaps as $from => $to ) { + if ( false !== $real && realpath( $root . '/' . $from ) === $real ) { + $config = $to; + break; + } +} + +echo $config;