pestphp/pest-plugin-drift
Pest Plugin Drift adds drift detection to your Pest test suite, helping catch behavioral changes and flaky differences across runs. Install alongside Pest to track and report unexpected output or snapshot mismatches during testing.
Installation
Add the plugin to your composer.json:
composer require --dev pestphp/pest-plugin-drift
Enable the plugin in pest.php:
plugins([
Pest\DriftPlugin::make(),
]);
First Use Case Write a test with drift detection:
test('user can login', function () {
$response = $this->post('/login', ['email' => 'user@example.com', 'password' => 'password']);
$response->assertOk();
$response->assertDrift(); // <-- Drift detection
})->drift(10); // Allow 10% drift
Where to Look First
tests/Feature/DriftTest.php (if included in the package)vendor/pestphp/pest-plugin-drift/src/DriftPlugin.php (core logic)Drift Detection in API Tests
test('GET /api/users returns paginated results', function () {
$response = $this->get('/api/users');
$response->assertOk()
->assertDrift()
->assertJsonStructure([...]);
})->drift(5); // 5% allowed drift
Conditional Drift Checks
test('database-heavy endpoints tolerate drift', function () {
if (config('app.env') === 'staging') {
$this->get('/reports')->assertDrift(15);
} else {
$this->get('/reports')->assertNoDrift();
}
});
Custom Drift Calculators
use Pest\DriftPlugin\Drift;
test('custom drift logic', function () {
$actual = $this->get('/analytics')->json();
$expected = file_get_contents('tests/data/analytics.json');
Drift::assertDrift($actual, $expected, function ($a, $b) {
return abs($a - $b) <= 0.1; // Custom tolerance
});
});
Drift in Feature Tests
test('livewire component renders with drift', function () {
$this->livewire(AnalyticsDashboard::class)
->assertDrift(10)
->assertSee('Total Users');
});
pest-plugin-laravel for seamless Laravel integration.$this->mock(Http::class, function ($mock) {
$mock->shouldReceive('get')
->andReturn(response()->json(['data' => 100]), 200);
});
test('handles mocked drift')->assertDrift(20);
False Positives
$response->assertDrift()->ignore('created_at', 'updated_at');
Performance Overhead
Strict Mode Conflicts
assertNoDrift() + assertExactJson() may conflict.Floating-Point Precision
Drift::assertDrift(round($actual, 2), round($expected, 2));
$response->assertDrift()->dumpDifferences();
pest.php:
plugins([
Pest\DriftPlugin::make()->logDriftEvents(),
]);
Global Drift Settings
Override defaults in pest.php:
plugins([
Pest\DriftPlugin::make()->defaultDrift(5)->strictMode(false),
]);
Environment-Specific Drift
Use .env to toggle drift checks:
test('drift enabled in staging')->drift(config('app.drift_threshold', 0));
Custom Assertions
Extend the plugin’s DriftAssertions trait:
use Pest\DriftPlugin\DriftAssertions;
trait CustomDriftAssertions {
use DriftAssertions;
public function assertCustomDrift($expected, $actual, $threshold = 10) {
// Custom logic
}
}
Pre-Test Hooks Modify drift behavior dynamically:
beforeEach(function () {
if ($this->actingAs('admin')) {
$this->enableDrift(20); // Higher tolerance for admins
}
});
Database Snapshots
Combine with pest-plugin-database for drift-aware DB tests:
test('database consistency')->assertDrift()->assertDatabaseHas(...);
How can I help you explore Laravel packages today?