PHPUnit suite refactor + CI overhaul#1660
Merged
Merged
Conversation
|
Coverage report for commit: 460ad8f Summary - Lines: 92.96% | Methods: 88.24% | Branches: 81.37%
🤖 comment via lucassabreu/comment-coverage-clover |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Coverage report for commit: 460ad8f Summary - Lines: 82.18% | Methods: 88.63%
🤖 comment via lucassabreu/comment-coverage-clover |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Closed
|
Coverage report for commit: 2228837 Summary - Lines: 92.96% | Methods: 88.24% | Branches: 81.37%
🤖 Jest coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Coverage report for commit: 2228837 Summary - Lines: 82.18% | Methods: 88.63%
🤖 PHPUnit coverage report |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6113ff0 to
84e83e0
Compare
End-to-end refactor of the PHPUnit suite and CI workflow. Headline outcomes:
Test architecture
- Mirror src/ 1:1 with Test_*.php naming; 32 root-level test-*.php files relocated to per-class files under tests/phpunit/integration/.
- Phase 4 characterization coverage for Controllers, Models, Helpers (Fields/Fonts), and Views; final coverage 81.57% (gate 81.45%).
- New AjaxTestCase parallel to WP_Ajax_UnitTestCase; shared HasGfpdfFixtures trait exposes form()/entry()/entries() accessors to both base classes.
- Skipped trivial exception classes and pure template wrappers per the documented "test if non-trivial" rule.
- tests/phpunit/README.md documents the suite layout, fixtures, and the available fixture keys.
Fixtures-to-factory migration (follow-up epic)
- Removed the suite-scoped $GLOBALS['GFPDF_Test'] global across 62 test files; bootstrap's create_stubs() deleted along with the orphan gravityform-2.json fixture.
- Replaced with per-class static::load_fixtures() declarations populating a protected $fixture_caches map on HasGfpdfFixtures.
- Two factory import paths preserved: import_and_get (array-wrapped GF-export JSON) and import_fixture_and_get (raw-object JSON used by load_fixtures).
- CI grep gate in .github/workflows/tests.yml blocks regression to \$GLOBALS['GFPDF_Test'], GFAPI::add_form, GFAPI::add_entry in test files.
- Suite is 1503 tests / ~4750 assertions / 14 skipped — ~40s single-site, ~38s multisite. Runtime improved vs the +10% budget because bootstrap no longer eagerly creates 7 forms + 5 entry sets.
Suite speed + stability
- Killed the sleep(1) flake in Test_Url_Signer; lifted gf_factory writes to class scope.
- Blocked external HTTP and stripped WP update probes from AJAX setup.
- Unique zip names per Test_Templates stage to kill cross-test flake.
- Closed leak vectors and shaved wall-clock across the suite; post-Phase-4 flake budget is zero.
- Dropped vendored Polls/Quiz/Survey plugins, replaced with a minimal class-stub surface for PHPUnit.
CI infrastructure
- Consolidated PHPUnit + Playwright + JS test workflows into a single tests.yml; extended deps update workflow.
- PR coverage now renders inline via lucassabreu/comment-coverage-clover (Codecov + token removed); coverage-merge.php unions single-site + multisite Clover before the comment step.
- tools/phpunit/retry.sh re-runs only the failing Class::method names parsed from JUnit XML once on flake; retries surface as ::warning::retry: annotations. --coverage-clover stripped from retry args so the full-suite Clover isn't overwritten by a single-test subset.
- wp-env Docker base images (wordpress:php<v>, wordpress:cli-php<v>, mariadb:lts) cached via docker save/load, removing ~60-90s per matrix cell / Playwright shard. docker/setup-buildx-action@v3 dropped — wp-env never used it.
- PHP floor wired to 7.4 in composer.json to match the Gravity Forms requirement.
- setup-php now matches \${{ matrix.php }} instead of hardcoded 7.4.
- Docker Hub pulls routed through Google's mirror to dodge rate limits.
- run-tests-php-all PR label opts into the full PHP-version matrix on demand (cron still runs it weekly); multisite runs on declarative floor (7.4) + ceiling (8.5) cells rather than the 8.3 coverage cell.
Known follow-ups (separate epics)
- Phase 6 Model_PDF refactor.
- 6 pre-existing order-coupled failures surface under --order-by=random (Test_Templates filesystem state, Test_Uninstaller/Test_Actions notices, Test_Rest_Pdf_Preview) — hidden by deterministic discovery order in the legacy suite; not introduced by this work.
Plans: .claude/plans/2026-05-25-phpunit-tests-refactor.md, .claude/plans/2026-05-26-fixtures-to-factory-migration.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84e83e0 to
2228837
Compare
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.
Summary
This PR refactors the PHPUnit suite and rebuilds the CI workflow around it.
The suite now mirrors
src/one-to-one withTest_*.phpnaming, so a failing test points straight at the class it covers. The old suite-scoped$GLOBALS['GFPDF_Test']fixtures are gone: each test class declares the forms and entries it needs viastatic::load_fixtures(), which keeps tests isolated and lets bootstrap stop eagerly building fixtures a given test may never touch. Phase 4 added characterization coverage for the largest Controllers, Models, Helpers, and Views, bringing total coverage to 81.57%.On the CI side, the separate PHPUnit, Playwright, and JS workflows are consolidated into one
tests.yml. PR coverage renders inline as a comment, Docker base images are cached to cut cold-start time, and a flaky test is retried once before it fails the run. PRs run a tightened PHP matrix (floor plus ceiling) for fast feedback; the weekly cron and the newrun-tests-php-alllabel run the full 7.4 to 8.5 matrix, and the multisite suite runs on the floor and ceiling cells.Try it
git fetch origin phpunit-refactor-squashed && git checkout phpunit-refactor-squashed yarn wp-env:integration start yarn test:php yarn test:php:multisiteTest plan
run-tests-php-alllabel expands the PR run to the full 7.4–8.5 matrix$GLOBALS['GFPDF_Test'],GFAPI::add_form,GFAPI::add_entry) reports cleantests.yml::warning::retry:annotations in the workflow log (a survivor would mean a real flake got past Phase 4)More info
Test architecture
src/1:1 withTest_*.phpnaming; relocated the 32 root-leveltest-*.phpfiles into per-class files undertests/phpunit/integration/.AjaxTestCaseparallel toWP_Ajax_UnitTestCase; sharedHasGfpdfFixturestrait exposesform()/entry()/entries()accessors to both base classes.tests/phpunit/README.mddocuments the suite layout, the fixture system, and the available fixture keys.Fixtures-to-factory migration (follow-up epic, same PR)
$GLOBALS['GFPDF_Test']global across 62 test files; bootstrap'screate_stubs()deleted along with the orphangravityform-2.jsonfixture.static::load_fixtures()declarations populating aprotected $fixture_cachesmap onHasGfpdfFixtures.import_and_get(array-wrapped GF-export JSON) andimport_fixture_and_get(raw-object JSON used byload_fixtures)..github/workflows/tests.ymlblocks regression to$GLOBALS['GFPDF_Test'],GFAPI::add_form,GFAPI::add_entryin test files.Suite speed + stability
sleep(1)flake inTest_Url_Signer; liftedgf_factorywrites to class scope.Test_Templatesstage to kill cross-test flake.CI infrastructure
tests.yml; extended the deps update workflow.lucassabreu/comment-coverage-clover(Codecov + token removed).tools/phpunit/coverage-merge.phpunions single-site + multisite Clover before the comment step.tools/phpunit/retry.shre-runs only the failingClass::methodnames (parsed from JUnit XML) once on flake; retries surface as::warning::retry:annotations.--coverage-cloveris stripped from retry args so the full-suite Clover isn't overwritten by a single-test subset.wordpress:php<v>,wordpress:cli-php<v>,mariadb:lts) cached viadocker save/docker load, removing ~60-90s of cold-pull per matrix cell / Playwright shard.docker/setup-buildx-action@v3removed from PHPUnit — wp-env never used it.composer.jsonto match what Gravity Forms (required dep) already needs;setup-phpnow matches${{ matrix.php }}instead of being hardcoded to 7.4.run-tests-php-allPR label opts into the full PHP-version matrix on demand (cron still runs it weekly). Multisite runs on declarative floor (7.4) + ceiling (8.5) cells via matrixincludeflags rather than the 8.3 coverage cell.Known follow-ups (separate epics)
Model_PDFrefactor.--order-by=random(Test_Templatesfilesystem state,Test_Uninstaller/Test_Actionsnotices,Test_Rest_Pdf_Preview) — hidden by deterministic discovery order in the legacy suite; not introduced by this work.Plans:
.claude/plans/2026-05-25-phpunit-tests-refactor.md,.claude/plans/2026-05-26-fixtures-to-factory-migration.md.🤖 Generated with Claude Code