Skip to content

Stop classifying a failing PHPUnit assertion as a Composer failure (#377) - #378

Merged
PabloCodes7 merged 1 commit into
mainfrom
fix/php-test-failure-not-composer
Jul 17, 2026
Merged

PabloCodes7 merged 1 commit into
mainfrom
fix/php-test-failure-not-composer

Conversation

@PabloCodes7

Copy link
Copy Markdown
Contributor

Closes #377.

The confident-wrong

A real failed run of symfony/symfony Unit Tests (8.3) (29551386048) installs its dependencies cleanly with composer update, runs the suite, and one assertion in ErrorHandler fails:

Failed asserting that an array has the key 'args'.
FAILURES!
Tests: 128, Assertions: 379, Failures: 1, Skipped: 2.
##[error]KO src/Symfony/Component/ErrorHandler

PatchRail answered php_composer_failure at 0.95 (on 0.6.1 and on the live PyPI 0.7.3) — telling a maintainer whose Composer step had gone green to go debug dependency installation.

Root cause

The php_composer_failure rule carried PHPUnit's own verdict markers (FAILURES!, Failed asserting, the Tests: … Failures: summary) as if a failing test were a failing install, and it counted the bare composer install/composer update commands that run in nearly every PHP job. The self-written zoo fixture php-phpunit-failure.log enshrined the same wrong answer.

Fix

  • Narrow the rule to witness only genuine dependency errors (Your requirements could not be resolved, requires php, a drifted lockfile, an unresolvable Problem N) and the autoload Class … not found.
  • A plain PHPUnit assertion failure now carries nothing here and lands on unknown — the honest ceiling, since PatchRail has no PHP test-failure class (same as ruff and svelte).
  • Correct the php-phpunit-failure fixture to expect unknown; lower the re-measured min-confidence on the lock-drift (0.85→0.7) and autoload (0.7→0.5) fixtures.
  • Commit the real symfony run as a real-world benchmark log, pinned by tests/test_php_test_failure_not_composer.py, and refresh docs/real-world-benchmark.md (twelfth log, five unknowns) + CHANGELOG.

Verification

  • patchrail ci benchmark examples/ci-triage: 223/223, top-1 = 1.0 (no regression). php_composer_failure now 5 fixtures, all passing; unknown 1 fixture.
  • All 10 previously-committed real-world logs return the identical verdict as before.
  • Genuine composer failures (unresolvable requirement, lockfile drift) still classify at full confidence — guarded by the new test.
  • Full suite: 958 passed; ruff check + format clean (Python 3.12).

)

php_composer_failure carried PHPUnit's own verdict markers (FAILURES!, Failed
asserting, the Tests: ... Failures: summary) plus the bare composer install/update
commands that run green in nearly every PHP job. A real symfony/symfony Unit Tests
run (29551386048) that installed cleanly and then failed one ErrorHandler assertion
was reported as php_composer_failure at 0.95, sending the maintainer to debug an
install that had succeeded.

Narrow the rule to genuine dependency errors (unresolvable requirement, platform
mismatch, drifted lockfile) and the autoload Class ... not found. A plain PHPUnit
test failure now carries nothing here and lands on unknown -- the honest ceiling,
since PatchRail has no PHP test-failure class. Genuine composer failures keep full
confidence; the 223-fixture zoo stays top-1 = 1.0.

- narrow php_composer_failure patterns; update likely_subsystem/repair strategy
- correct the self-written php-phpunit-failure fixture to expect unknown; lower
  min-confidence on lock-drift and autoload fixtures to their re-measured values
- commit the real symfony run as a real-world benchmark log + pin it with a test
- refresh docs/real-world-benchmark.md (twelfth log, five unknowns) and CHANGELOG
@PabloCodes7
PabloCodes7 merged commit bff7637 into main Jul 17, 2026
5 checks passed
@PabloCodes7
PabloCodes7 deleted the fix/php-test-failure-not-composer branch July 17, 2026 10:11
@PabloCodes7 PabloCodes7 mentioned this pull request Jul 21, 2026
PabloCodes7 added a commit that referenced this pull request Jul 21, 2026
Cut 0.7.4 from main. The last release, 0.7.3 (2026-07-16), predates ten
false-positive fixes that are sitting on main and not on PyPI: an installed
pytest read as a failing test run (#376), a passing test's title read as a
secrets failure (#380), a PHPUnit assertion read as a Composer failure (#378),
Flutter's cached Gradle Wrapper (#382), Cabal's dependency resolution read as
Maven (#383), Crystal and dune's make targets read as C/C++ (#384, #385), a
parenthesized 504 (#391), mypy in a pixi manifest (#390), an unset TERM read as
a missing secret (#392), a warning-only yarn install and a recovered checkout
(#393), and a verdict held up by invocations alone reporting diagnosis-level
confidence (#395). Every one of those is a wrong answer a maintainer gets today
from pip install patchrail.

Version bumped in the four places that spell it out (pyproject, __init__,
README quickstart, uv.lock), CHANGELOG's Unreleased section dated, and the
real-world benchmark's release-status paragraph corrected: it no longer claims
six fixes are unreleased.

Co-authored-by: PabloCodes7 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

php_composer_failure: a failing PHPUnit assertion is classified as a Composer failure at 0.95

1 participant