spatie/phpunit-snapshot-assertions
Add snapshot testing to PHPUnit. Save expected output (JSON, arrays, strings, etc.) on first run and automatically compare on later runs to catch regressions with minimal assertions. Includes handy traits and snapshot update workflow for tests.
assertJson()/assertEquals() chains for dynamic data. It’s particularly useful for:
assertMatchesJsonSnapshot($response->json())).assertMatchesHtmlSnapshot($view->render())).assertMatchesTextSnapshot($commandOutput)).--parallel flag).composer require --dev spatie/phpunit-snapshot-assertions), with zero Laravel-specific configuration. The MatchesSnapshots trait requires minimal boilerplate (e.g., use Spatie\Snapshots\MatchesSnapshots).Collection serialization).CREATE_SNAPSHOTS, UPDATE_SNAPSHOTS) enable controlled snapshot management in pipelines (e.g., fail builds on missing snapshots in CI, auto-update in dev).assertMatchesJsonSnapshot($response, 'user-profile')) and combine with partial assertions (e.g., assertJsonStructure()).__snapshots__/ over time, requiring periodic cleanup.composer script to prune old snapshots (e.g., git clean -f __snapshots__).CREATE_SNAPSHOTS=false) and use UPDATE_SNAPSHOTS in dev with sequential runs.HasFactory models).json_encode() to exclude non-deterministic fields like created_at).data in {"data": {...}, "meta": {...}})?composer update-snapshots locally and restrict CI to CREATE_SNAPSHOTS=false.assertJson()) or augment them?phpunit --stop-on-failure; use file hash snapshots (assertMatchesFileHashSnapshot) for large binaries.snapshot() helper (if using pest-plugin-snapshots).assertJson() chains with assertMatchesJsonSnapshot($response->json()).assertMatchesHtmlSnapshot($view->render()).assertMatchesTextSnapshot($command->output()).assertMatchesHtmlSnapshot($livewire->render())).assertMatchesTextSnapshot($mailable->render()).public function test_login_response()
{
$response = $this->post('/login', ['email' => 'user@example.com']);
$this->assertMatchesJsonSnapshot($response->json(), 'login-success');
}
assertEquals() for complex objects (e.g., Eloquent models) with assertMatchesObjectSnapshot().public function test_user_serialization()
{
$user = User::factory()->create();
$this->assertMatchesObjectSnapshot($user);
}
{
"scripts": {
"test": "phpunit",
"update-snapshots": "UPDATE_SNAPSHOTS=true phpunit",
"clean-snapshots": "rm -rf __snapshots__"
}
}
# .github/workflows/tests.yml
env:
CREATE_SNAPSHOTS: false
spatie/phpunit-snapshot-assertions:^1.0.^1.0.CREATE_SNAPSHOTS=false in CI (see Usage with parallel testing).git config --global core.autocrlf input) to avoid snapshot diff issues.UPDATE_SNAPSHOTS=true).feature-name__output-type).CREATE_SNAPSHOTS=false).git add __snapshots__ before major releases).__snapshots__/UserTest__test_profile__1.json).composer clean-snapshots).pre-release script to prune old snapshots.composer update-snapshots after changing test data.json_encode() defaults). Example:
// Custom driver for Laravel 10+ JSON encoding
class LaravelJsonDriver implements Driver {
public function serialize($data): string {
return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
// ...
}
--- Expected/+++ Actual).assertMatchesFileSnapshot to generate side-by-side comparisons.How can I help you explore Laravel packages today?