Skip to content

feat(runner): report a test that only passed on retry as flaky - #1040

Merged
Chemaclass merged 1 commit into
mainfrom
feat/1012-flaky-status
Aug 10, 2026
Merged

feat(runner): report a test that only passed on retry as flaky#1040
Chemaclass merged 1 commit into
mainfrom
feat/1012-flaky-status

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #1012

--retry hid flakiness instead of surfacing it. A test that failed and then passed was recorded as a plain pass, with the only trace a console suffix that never reached the counters or any report. A CI job that retried a flaky test was indistinguishable from a clean run, so flakiness never got triaged.

💡 Changes

  • Flaky is now a first-class outcome: a test that only passed after a retry is counted separately and reported as Flaky: N in the summary.
  • It stays inside the pass total, so the default exit code is unchanged. --fail-on-flaky turns such a run red, mirroring --fail-on-risky.
  • The first attempt's failure message, previously discarded when the retry overwrote it, is preserved and carried into JUnit (<flakyFailure>), TAP, JSON, HTML and the GitHub Actions annotations along with the retry count.
  • Counters stay correct under --parallel: the retry count crosses the fork in the per-test payload, which the aggregator reads and defaults on its own.

--retry hid flakiness instead of surfacing it. A test that failed and
then passed was recorded as a plain pass; the only trace was a console
suffix, absent from the counters, from JUnit, TAP, JSON and HTML, and
from the GitHub Actions annotations. A CI job that retried a flaky test
looked exactly like a clean run.

Flaky is now a facet of passed, not a seventh outcome: the test is still
counted in the pass total, so the exit code is unchanged unless
--fail-on-flaky is given, and the flaky count is deliberately left out of
the total to keep it from exceeding the tests actually run.

The first attempt's failure message is the whole diagnostic value and was
being overwritten by the next attempt, so it is captured before the retry
loop discards it and carried into every report.

The retry count lives in the runner shell, not in the test subshell that
builds the payload, so it is appended to the payload after the loop. That
is what lets it cross the fork: the parallel aggregator re-derives every
status from the .result file and would otherwise see a plain pass. The
field is read and defaulted on its own there, because a payload without
it would leave the strip a no-op and hand the numeric guard arbitrary
text, marking every test failed.

Closes #1012
@Chemaclass Chemaclass added the enhancement New feature or request label Aug 10, 2026
@Chemaclass Chemaclass self-assigned this Aug 10, 2026
@Chemaclass
Chemaclass merged commit f420251 into main Aug 10, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/1012-flaky-status branch August 10, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant