Skip to content

Add wrapper binaries to replace -d --update-snapshots syntax#245

Merged
freekmurze merged 6 commits into
mainfrom
feature/update-snapshots-binary
Apr 29, 2026
Merged

Add wrapper binaries to replace -d --update-snapshots syntax#245
freekmurze merged 6 commits into
mainfrom
feature/update-snapshots-binary

Conversation

@freekmurze
Copy link
Copy Markdown
Member

Summary

Closes #242.

Since PHPUnit 12.5.12, the documented phpunit -d --update-snapshots form produces a Failed to set "--update-snapshots=1" test runner warning, because it abuses PHPUnit's -d flag (which is designed to set php.ini values).

This PR ships two wrapper binaries that set the corresponding env var before invoking PHPUnit, so users keep a single short command without triggering the warning:

  • vendor/bin/update-snapshots (sets UPDATE_SNAPSHOTS=true)
  • vendor/bin/without-creating-snapshots (sets CREATE_SNAPSHOTS=false)

Both binaries pass through all argv to PHPUnit, so vendor/bin/update-snapshots tests/OrderTest.php --filter=foo works as expected.

What changed

  • bin/update-snapshots, bin/without-creating-snapshots: PHP shims registered via composer.json's bin array. They locate PHPUnit via $GLOBALS['_composer_autoload_path'] (when invoked through Composer's bin proxy) or via path candidates relative to the script.
  • src/MatchesSnapshots.php: shouldUpdateSnapshots() and shouldCreateSnapshots() now check the env var first, falling back to argv detection for backwards compatibility. Exception messages and PHPDoc updated to point at the new approach.
  • tests/Integration/MatchesSnapshotTest.php: updated assertions for the new exception messages.
  • README.md: replaced -d --update-snapshots recommendations with the wrapper binary, documented the env var and Composer script alternatives, and added a "Why not phpunit -d --update-snapshots?" callout linking to the upstream PHPUnit commit.

Verification

  • vendor/bin/phpunit tests/Integration/MatchesSnapshotTest.php: 33 tests, 131 assertions, all green.
  • Manually verified on PHPUnit 12.5.23: the wrapper produces no test runner warning, while the legacy -d --update-snapshots form does.
  • Manually verified that getenv('UPDATE_SNAPSHOTS') returns 'true' inside test code when invoked via the wrapper, and is unset for plain vendor/bin/phpunit.

Backwards compatibility

The argv detection (in_array('--update-snapshots', $_SERVER['argv'], true)) is kept, so existing CI pipelines using -d --update-snapshots continue to work, just with the PHPUnit warning. The README marks the legacy syntax as deprecated.

freekmurze and others added 6 commits April 29, 2026 10:49
Since PHPUnit 12.5.12, the documented `phpunit -d --update-snapshots`
form produces a `Failed to set "--update-snapshots=1"` test runner
warning because it abuses PHPUnit's `-d` flag.

This commit ships `vendor/bin/update-snapshots` and
`vendor/bin/without-creating-snapshots` wrapper binaries that set the
`UPDATE_SNAPSHOTS` / `CREATE_SNAPSHOTS` environment variables before
running PHPUnit, which avoids the warning. The legacy CLI argument
detection is kept for backwards compatibility.

The README and exception messages now point to the new approach and
document the env var + Composer script pattern as alternatives.

Closes #242

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Extract shared `bin/_run-phpunit.php` so both wrappers share the
  PHPUnit-locator logic instead of duplicating ~18 lines.
- Add a one-line comment explaining why the env var is set via
  putenv(), $_ENV[] and $_SERVER[] (so reads from any of them see it
  regardless of the user's variables_order ini setting).
- Reword the "snapshot does not exist" failure message to present the
  two remediations as independent options instead of implying the
  user invoked the wrapper binary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove `bin/without-creating-snapshots` and its README/composer entries;
  CREATE_SNAPSHOTS=false is the only documented way to disable creation.
- The argv check in `shouldCreateSnapshots()` is kept for backwards
  compatibility, but the binary is no longer shipped.
- `bin/update-snapshots` now captures the prior UPDATE_SNAPSHOTS state
  (across getenv(), $_ENV, $_SERVER) and restores it via a shutdown
  handler, so the wrapper does not leave the env var mutated for any
  in-process code that runs after PHPUnit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PHPUnit 12.5 tracks `AssertionFailedError` thrown from a mock as a
test failure even when the calling test catches it. The `expectFail`
helper relied on the older behaviour, which is what caused 9 tests to
fail on PHPUnit 12.5 (reproducible on `main` independently of this PR).

Switch the mock's exception to a plain `RuntimeException` carrying the
expected message, and assert via `expectException` /
`expectExceptionMessage`. This restores test isolation without changing
production behaviour.

Also add `UpdateSnapshotsBinaryTest` covering the wrapper's three
contracts: setting `UPDATE_SNAPSHOTS=true` for the inner PHPUnit run,
restoring an unset env var on shutdown, and restoring a prior value on
shutdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the two `WasSet` flags by treating `null` as the "wasn't set"
sentinel (env values are always strings, so null is unambiguous).
Replace the if/else for putenv with a ternary, and the if/else for
$_ENV / $_SERVER restoration with `unset()` followed by guarded re-set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread bin/_run-phpunit.php
@freekmurze freekmurze merged commit b5ad3ef into main Apr 29, 2026
269 of 306 checks passed
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.

Since PHPUnit 12.5.12, -d --... causes warnings

2 participants