Pest brings the joy of testing to PHP — for you and your coding agents. Browser testing and AI evals are built in, and agents verify their own work, end to end.
Backed by teams
who ship with Pest
// test with confidence
// tia — test impact analysis
$ ./vendor/bin/pest --tia
~ src/Button.tsx changed
→ running 9 affected tests, replaying 765 from cache
✓ it may login — 0.21s
✓ it may checkout — 0.18s
Tests: 774 passed (9 affected, 765 replayed)
Duration: 0.74s
// suite duration — full run vs tia
pest
15.2s
pest --tia
0.74s
// tia engine
Only run the tests that matter
Test Impact Analysis maps your whole suite to the code each test depends on, so a change to one file re-runs only the tests it can break. A 15-second suite comes back in under a second, fast enough for an agent to run it after every edit.
FAIL Tests\MathTest
× it adds numbers
FAILED Tests\MathTest > adds numbers
Failed asserting that 2 is identical to 3.
at tests/MathTest.php:4
1<?php
2
3it('adds numbers', function () {
→4 expect(1 + 1)->toBe(3);
5});
Tests: 1 failed, 773 passed (2658 assertions)
Duration: 4.18s
// readable failures
Failures that explain themselves
A failed test prints the assertion, the diff and the exact line of code in your terminal. Most of the time you know the fix before you open the editor.
parallel coverage browser testingnew architecture snapshot mutation stress evalsnew profiling type coverage tia enginenew
// all-in-one framework
Everything you need to test your app
Parallel execution, coverage, mutation and snapshots ship in the box. You install Pest once and stop assembling a toolchain.
it('may login', function () {
visit('/login')
->type('email', 'hi@example.com')
->type('password', 'password')
->press('Continue')
->assertSee('Dashboard')
->assertNoJavascriptErrors();
});
// modern browser testing
Run browser tests with Pest
Browser tests are plain Pest tests. Playwright drives a real browser while you keep the syntax and the suite you already have.
$ pest --agent='visit("/checkout")->assertNoJavascriptErrors();'
✓ verify — page loaded · 0 js errors · 0 console warnings
agent → checking the fix on mobile…
$ pest --agent='visit("/checkout")->on()->mobile()->screenshot(filename: "checkout");'
✓ verify — layout stable · screenshot saved to .pest/screenshots
agent → verifying the backend too…
$ pest --agent='$order = \App\Models\Order::factory()->create(); expect($order->total)->toBeGreaterThan(0);'
✓ verify — 1 passed (1 assertion)
// agent browser
Your agents verify their own work
A coding agent can check its own change against your live app with one short CLI command: visit the page, assert on what rendered, save a screenshot as proof. Each probe runs as an isolated, throwaway test, so nothing extra lands in your suite.
it('answers support questions', function () {
expect(SupportAgent::class)
->prompt('How do I reset my password?')
->repeat(50)
->toBeCorrect()
->toBeSafe(0.9)
->toSatisfy('Gives the password reset steps');
});
// pest --evals — 50 samples 96%
// ai evals
Eval your LLM features like code
Evals are ordinary Pest tests. Assert exact strings where the answer is fixed, and let AI scorers grade relevance or safety where it is not. When a prompt regresses, CI fails.
The biggest release of Pest yet — for most suites, a one-line upgrade.