Add two-tier PHP test harness (#1051)#1064
Merged
Merged
Conversation
Make the procedural caching functions reachable from PHPUnit, split into two tiers by what they need to run: Smoke tier (CI, no database, no WordPress runtime): - tests/php/bootstrap-smoke.php loads the procedural files and provides a minimal pure-PHP filter registry (add_filter/apply_filters/ remove_all_filters) standing in for WordPress's hook system. - Tests in tests/php/smoke/ for supercache_filename() (a #1050 filename-sanitization regression guard), wpsc_get_realpath() + wpsc_is_in_cache_directory(), get_wp_cache_key(), plus the existing accept-header test moved in. - phpunit.{9,11,12}.xml.dist now target the smoke bootstrap + tests/php/smoke. Integration tier (local only, via `make test-integration`): - tests/php/bootstrap-integration.php loads the WordPress test library and the procedural files under a real WP runtime + database. No apply_filters stub — WordPress core defines the real one. - Runs in the wp-env Docker environment. Because WP_UnitTestCase is not PHPUnit 10+ compatible while the smoke tier runs modern PHPUnit, the integration tier uses an isolated PHPUnit 9 toolchain in tests/php/tools/. - phpunit-integration.{9,11,12}.xml.dist + tests/php/wp-tests-config.php (env-driven, wp-env defaults). Other: - Makefile: `make test` (smoke) and `make test-integration` (Docker). - .wp-env.json bumped to PHP 8.3 (drops deprecated testsEnvironment key). - tests/php/README.md documents the copyable pattern for each tier.
WordPress's WP_UnitTestCase calls PHPUnit\Util\Test::parseTestMethodAnnotations(),
removed in PHPUnit 10+, so the integration tier is capped at PHPUnit 9.6 (verified
against PHPUnit 10.5 and 12.5 — both fatal). Rather than run the smoke tier on
modern PHPUnit and the integration tier on an isolated 9.x toolchain, pin the
whole project to PHPUnit 9.6, matching the version WordPress core tests against.
- composer.json: pin phpunit/phpunit ^9.6; wp-phpunit back in root require-dev.
- Remove tests/php/tools/ (the isolated PHPUnit 9 toolchain) entirely.
- Remove phpunit.{11,12}.xml.dist and phpunit-integration.{11,12}.xml.dist;
only the .9 configs remain.
- bootstrap-integration.php: drop the WPSC_INTEGRATION_AUTOLOAD indirection —
both tiers share the root vendor again.
- Makefile: test-integration runs vendor/bin/phpunit directly (no isolated
install, no platform pin, no env-var plumbing).
- README: note both tiers run on PHPUnit 9.6 and why.
Verified: composer test-php (smoke, PHP 8.5) OK 34/42; make test-integration
(real WP + DB) OK 2/2.
PHPUnit 9.6 (the version the project is now pinned to) does not read the #[CoversFunction] attribute API (PHPUnit 10+), so the attributes recorded no coverage attribution. Switch the smoke tests and the README example to the 9.x-native @Covers ::function annotation so coverage runs (composer test-coverage) attribute coverage to the function under test.
Code-review follow-ups: - Guard _wpsc_manually_load_procedural_files() with function_exists() so the integration bootstrap can't fatal on redeclaration if the plugin is ever active in the tests env and loads wp-cache-phase2.php via WPCACHEHOME. - README: note that the composer test-php / phpunit scripts use pcntl (via phpunit-select-config) and how to run PHPUnit directly without it.
npx --yes @wordpress/env re-resolves the package against the npm registry on every make invocation, which fails behind registry proxies that gate or block fetches. Pin @wordpress/env as a devDependency and point the Makefile at node_modules/.bin/wp-env so it resolves locally after a one-time npm install (make install), with no per-run registry round-trip.
Add a file-target rule for node_modules/.bin/wp-env that exits with a clear message when the binary is missing, and make every wp-env target depend on it. Replaces the raw 'No such file or directory' failure when wp-env hasn't been installed yet.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1051.
Makes the procedural caching functions reachable from PHPUnit, split into two tiers by what they need to run. Both tiers run on PHPUnit 9.6 — see the version note below.
Smoke tier — CI, no database, no WordPress runtime
tests/php/bootstrap-smoke.phploads the procedural caching files and provides a minimal, pure-PHP filter registry (add_filter/apply_filters/remove_all_filters) standing in for WordPress's hook system — enough to test WordPress-free functions and to inject filter input.tests/php/smoke/:SupercacheFilenameTest— Restrict supercache filename to a safe character set #1050 filename-sanitization regression guard (hostilesupercache_filename_strfilter output is reduced to a single, separator-free path segment).WpscRealpathTest—wpsc_get_realpath()+wpsc_is_in_cache_directory()path containment, against real temp dirs.GetWpCacheKeyTest— cache-key composition.WpscParseAcceptHeaderTest— moved in fromtests/php/.phpunit.9.xml.disttargets the smoke bootstrap andtests/php/smoke.composer test-phpacross PHP 8.2–8.5, no MySQL service.Integration tier — local only, via
make test-integrationtests/php/bootstrap-integration.phploads the WordPress test library (wp-phpunit/wp-phpunit) and the procedural files under a real WP runtime + database. Noapply_filtersstub — WordPress core defines the real one.tests/php/wp-tests-config.phpis environment-driven with wp-env defaults.phpunit-integration.9.xml.dist+ an exampleWP_UnitTestCasetest demonstrating the copyable pattern.Why PHPUnit 9.6 for everything
WordPress's
WP_UnitTestCasecallsPHPUnit\Util\Test::parseTestMethodAnnotations(), removed in PHPUnit 10+, so the integration tier is capped at PHPUnit 9.6 (verified: PHPUnit 10.5 and 12.5 both fatal with the latestwp-phpunit6.9.4). Since the integration tier can't move past 9.6 regardless, the whole project is pinned to PHPUnit 9.6 — one version, no isolated toolchain, matching the version WordPress core itself tests against. (An earlier revision of this PR ran the smoke tier on modern PHPUnit with a separate 9.x toolchain for integration; that split has been removed in favour of this simpler unified setup.)Other
Makefile:make test(smoke, no Docker) andmake test-integration(auto-starts wp-env)..wp-env.json: dropped the deprecatedtestsEnvironmentkey; bumpedphpVersion8.1 → 8.3.tests/php/README.mddocuments how to add a test to each tier.Verification
composer test-php→ OK (34 tests, 42 assertions) on PHP 8.5 / PHPUnit 9.6.make test-integration→ OK (2 tests, 2 assertions) under real WordPress + database.composer lint→ clean;php -lclean on all new files.Out of scope (per the issue)
wp-cache.phpfile-move split (Refactor: split wp-cache.php into per-responsibility inc/ files (pure move, test-net first) #1061) and the config write-path module (Refactor: introduce a Config module to own the config-file write path #1062), which consume this harness.