spatie/pest-plugin-test-time
Pest plugin to control time in tests via Carbon::setTestNow(): freeze “now” and easily move it forward/backward (e.g., addMinute). Includes a toBeCarbon expectation for asserting Carbon dates/times and formats.
Install the plugin via Composer: composer require --dev spatie/pest-plugin-test-time. It requires Pest ≥2.0 and PHP ≥8.1. Once installed, it’s auto-discovered—no configuration needed. Your first use case: testing an order’s expiration logic. Instead of manually calling Carbon::setTestNow(), write:
use function Spatie\TestTime\times;
test('order expires after 24 hours', function () {
times('2025-01-01 10:00:00')->freeze();
$order = Order::create(['expires_at' => now()->addDay()]);
expect($order->isExpired())->toBeFalse();
times()->travel(25 hours);
expect($order->isExpired())->toBeTrue();
});
Start by reading the README and checking tests/ examples in the repo—most patterns are immediately intuitive.
times(...)->freeze() inside individual tests; the plugin auto-resets time between tests (no afterEach required).times('2025-01-01')->travel(3 days)->freeze() for multi-step workflows (e.g., subscription trial → renewal).now(), Carbon::parse(), Artisan::call(), queued jobs, and scheduled tasks—no stubs or mocks needed.times('2025-03-10 14:00')->freeze();
$user = User::factory()->create(['created_at' => now()->subMonth()]);
expect($user->isNew())->toBeFalse();
travel(2, 'hours') or travel(1, 'day').time(): This plugin only affects Carbon/Laravel time helpers (now(), Carbon::now()). System time() and mktime() remain unchanged—avoid mixing them. Use Carbon::setTestNow() only as a fallback.freeze() stops time; subsequent travel() calls shift from that frozen point, not real wall-clock time. Never call freeze() inside a closure passed to travel()—it’s redundant.times() in beforeEach() unless you want time to persist across tests (e.g., testing cron-based jobs). Prefer times() per-test for determinism.Spatie\TestTime\TimeFactory or mock the TimeFactory interface.times()->now() to inspect the current test-time in assertions or logs—e.g., dd(times()->now()) to verify your travel chain.How can I help you explore Laravel packages today?