Build/Test Tools: Flag slow PHPUnit tests with annotations - #13212
Build/Test Tools: Flag slow PHPUnit tests with annotations#13212lancewillett wants to merge 1 commit into
Conversation
Parse the JUnit report from the canonical PHP 8.5 report job and emit GitHub Actions warning annotations plus a run-summary table for tests over a threshold, on pull requests and pushes to trunk. Advisory only: the step runs even on failed test runs and never fails the build itself. This names the slow tests, complementing the aggregate CodeVitals trend that stores them without naming any one test. See #65887.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @lance.willett@a8c.com. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
There was a problem hiding this comment.
Pull request overview
This PR adds CI tooling to surface individual slow PHPUnit tests during GitHub Actions runs by parsing the generated JUnit report and emitting GitHub Actions warning annotations plus a step-summary Markdown table, targeting the canonical PHP 8.5 reporting job context.
Changes:
- Added a new PHP CLI script to parse
junit.xml, identify tests exceeding a configurable threshold, and emit warning annotations and a run summary. - Integrated a new “Flag slow PHPUnit tests” step into the reusable PHPUnit workflow (gated to PHP 8.5 + reporting-enabled runs on PRs and trunk pushes).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
tests/phpunit/prepare-slow-test-annotations.php |
New CLI parser that finds slow testcases in JUnit XML and outputs GitHub Actions annotations + a step summary table. |
.github/workflows/reusable-phpunit-tests-v3.yml |
Adds a workflow step that runs the new parser after the main PHPUnit run under the intended conditions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if: >- | ||
| always() && inputs.report && inputs.php == '8.5' && | ||
| ( github.event_name == 'pull_request' || | ||
| ( github.event_name == 'push' && github.ref == 'refs/heads/trunk' ) ) |
adimoldovan
left a comment
There was a problem hiding this comment.
One PHPCS error fails the build. The rest are small.
Two points that map to no line in the diff:
- #13083 adds class-wp-phpunit-timing-metrics.php, which streams the same junit.xml at the same point in the same workflow. Once it lands, this script should reuse it rather than walk the file a second time.
- The job's # Performs the following steps: list (lines 110-129) omits this step. #13083 updates that list for its own step.
| "Usage: php tests/phpunit/prepare-slow-test-annotations.php <junit-file> " | ||
| . "[threshold-seconds] [max-annotations]\n" |
There was a problem hiding this comment.
This fails the build. The string holds no variable and no escape, so Squiz.Strings.DoubleQuoteUsage rejects the double quotes. Coding standards / PHP checks is the only red check on the PR.
| "Usage: php tests/phpunit/prepare-slow-test-annotations.php <junit-file> " | |
| . "[threshold-seconds] [max-annotations]\n" | |
| 'Usage: php tests/phpunit/prepare-slow-test-annotations.php <junit-file> ' | |
| . "[threshold-seconds] [max-annotations]\n" |
| } | ||
| ); | ||
|
|
||
| $slow_tests = array_slice( $slow_tests, 0, $max_annotations ); |
There was a problem hiding this comment.
The max-annotations argument caps the summary table, not the annotations, which line 214 caps separately at 10. The name says the opposite of what the value does. The table then stops at 20 rows with no marker, so it reads as complete when it is not.
| if ( '' !== $test['file'] ) { | ||
| $properties[] = 'file=' . wp_phpunit_escape_command_property( $test['file'] ); | ||
| } | ||
|
|
||
| if ( '' !== $test['line'] ) { | ||
| $properties[] = 'line=' . wp_phpunit_escape_command_property( $test['line'] ); | ||
| } |
There was a problem hiding this comment.
A testcase with line and no file emits ::warning line=60,..., which GitHub ignores. PHPUnit sets both together from reflection, so this branch never fires on a real report — tidying only.
| if ( '' !== $test['file'] ) { | |
| $properties[] = 'file=' . wp_phpunit_escape_command_property( $test['file'] ); | |
| } | |
| if ( '' !== $test['line'] ) { | |
| $properties[] = 'line=' . wp_phpunit_escape_command_property( $test['line'] ); | |
| } | |
| if ( '' !== $test['file'] ) { | |
| $properties[] = 'file=' . wp_phpunit_escape_command_property( $test['file'] ); | |
| if ( '' !== $test['line'] ) { | |
| $properties[] = 'line=' . wp_phpunit_escape_command_property( $test['line'] ); | |
| } | |
| } |
| # Runs even when the test step failed (always()), so the signal still | ||
| # surfaces on red runs, and never fails the job itself (continue-on-error), | ||
| # because this is advisory only. | ||
| if: >- |
There was a problem hiding this comment.
always() also runs the step on cancelled jobs, and phpunit-tests.yml sets cancel-in-progress: true, so PR runs are cancelled often. !cancelled() matches the intent.
Trac ticket: https://core.trac.wordpress.org/ticket/65887
What this changes
Adds a
Flag slow PHPUnit testsstep to the canonical PHP 8.5 report job. It parses the JUnit report and, for tests over a threshold (default 1s), emits GitHub Actions warning annotations and a run-summary table naming the slowest tests. Runs on pull requests and pushes to trunk.This complements #13083: those six CodeVitals aggregates store the trend but cannot name a test. This one names the slow ones, so a PR author can spot a slow test they added.
Behavior
always()) and never fails the build (continue-on-error).Use of AI Tools
AI assistance: Yes
Tool(s): Codex (via Claude Code), hardened with an adversarial multi-lens review
Used for: drafting the workflow step and PHP script, and reviewing it before submission.