Pest 5.0: Modern PHP AI Testing Framework Powered by PHP 8.4 & PHPUnit 13
Pest 5, built on PHP 8.4 and PHPUnit 13, introduces the Tia engine that cuts a ten‑minute Laravel test suite to about four seconds, adds an Agent plugin for AI‑driven verification, Evals for LLM assessment, PHPStan integration, Rector‑based auto‑refactoring, time‑balanced sharding and dozens of new assertions, all ready for production.
Pest 5 Official Release
Pest 5, the most important version to date, is built on PHP 8.4 and PHPUnit 13 and incorporates the features refined throughout the Pest 4 iteration cycle. All components are stable and production‑ready.
Tia Engine : Re‑runs only tests impacted by recent code changes, reducing a typical Laravel suite from ten minutes to about four seconds while preserving exact coverage data.
Agent Plugin : Adds a --agent option that lets an AI coding agent verify code changes with a single command; when the browser‑testing plugin is installed, it can drive a real browser to validate side effects.
Evals Capability : Enables evaluation of large language model agents directly in the test suite via the familiar expect() API, combining deterministic assertions with AI scoring (relevance, similarity, safety, etc.).
Official PHPStan Plugin : Makes PHPStan understand Pest’s functional API ( it(), test(), expect(), $this, etc.) and adds Pest‑specific static‑analysis rules.
Rector Auto‑Refactor : Provides dozens of Rector‑driven rules that modernise test code, converting native PHP assertions to expressive Pest syntax.
Time‑Balanced Test Sharding : Distributes test shards based on actual execution time rather than test count, ensuring all CI machines finish simultaneously.
New Assertion Methods : Adds toBeEmail(), toBeUlid(), toBeIpAddress(), toBeMacAddress(), toBeHostname(), toBeDomain(), toBeBase64(), toBeHexadecimal(), all negatable with not.
Upgrading to Pest 5
For most projects, upgrade by changing a single line in composer.json:
- "pestphp/pest": "^4.0",
+ "pestphp/pest": "^5.0",All official Pest plugins must also be upgraded to the ^5.0 version. Pest 5 requires PHP ≥ 8.4.
Note: See the official upgrade guide for the full change list.
Tia Engine
The Tia (Test Impact Analysis) engine re‑runs only tests affected by the latest code changes. Use it by adding the --tia flag to any Pest command: ./vendor/bin/pest --parallel --tia On first run it builds a test‑file dependency graph (requires PCOV or Xdebug). Subsequent runs replay cached results for unaffected tests. A typical Laravel suite that originally took 10 minutes now finishes in about 4 seconds:
Tests: 774 passed (2658 assertions, 7 affected, 2 uncached, 765 replayed)
Duration: 3.92sReplay preserves exact coverage data, and the dependency graph recognises the whole tech stack (e.g., Laravel, Symfony, Livewire, Inertia, front‑end assets).
Agent Plugin
Install the plugin:
composer require pestphp/pest-plugin-agent --devThe plugin adds a --agent option that runs a code snippet inside the full Pest environment. Example:
./vendor/bin/pest --agent='$user = \App\Models\User::factory()->create(); $this->actingAs($user)->get("/dashboard")->assertOk();'If the browser‑testing plugin is also installed, the agent can drive a real browser to verify side effects such as email delivery after a form submission:
./vendor/bin/pest --agent='visit("/")->assertSee("Welcome");'Unlike pure browser tools, the Agent plugin validates the entire request‑response chain, including queue jobs, emails, and database writes.
Evals Capability
Install the plugin:
composer require pestphp/pest-plugin-evals --devWrite evaluation tests that combine deterministic assertions with AI scoring:
use App\Agents\CapitalCityAgent;
it('can correctly answer capital city questions', function(): void {
expect(CapitalCityAgent::class)
->prompt('What is the capital of France?')
->toContain('Paris') // deterministic check
->toBeRelevant() // LLM relevance score
->toBeSimilar('Paris, France'); // semantic similarity
});Regular test runs skip these cases; add the --evals flag to execute them:
# Skip evals (no API calls)
./vendor/bin/pest
# Run evals (real model calls)
./vendor/bin/pest --evalsAdditional evaluation methods include toBeSafe(), toBeFactual(), toFollowTrajectory(), and repeat(), and custom scorers can be written.
Official PHPStan Plugin
Install the plugin and PHPStan:
composer require pestphp/pest-plugin-phpstan --dev
composer require phpstan/phpstan --devIf you use phpstan/extension-installer, the plugin registers automatically; otherwise add the extension to phpstan.neon:
includes:
- vendor/pestphp/pest-plugin-phpstan/extension.neonAfter configuration, PHPStan fully understands Pest’s API, including chained assertions like expect($user)->name->toBe('Nuno'), and flags meaningless assertions such as expect(10)->toStartWith('1').
Rector Auto‑Refactor Capability
Install the plugin and Rector:
composer require pestphp/pest-plugin-rector --dev
composer require rector/rector --devAdd the preset rule set to rector.php:
use Pest\Rector\Set\PestSetList;
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([__DIR__ . '/tests'])
->withSets([
PestSetList::CODING_STYLE,
]);Run a dry‑run to preview changes, then apply them. The rule set currently provides 60 refactoring rules.
Time‑Balanced Test Sharding
Generate shard timing data: ./vendor/bin/pest --update-shards This creates tests/.pest/shards.json, which should be committed. When the --shard flag is used, Pest distributes tests based on recorded execution times: ./vendor/bin/pest --shard=1/4 New test files added before updating the timing data are still executed, and Pest prompts you to refresh the shard data when needed.
New Assertion Methods
Pest 5 adds many ready‑to‑use assertions such as toBeEmail(), toBeUlid(), toBeIpAddress(), toBeMacAddress(), toBeHostname(), toBeDomain(), toBeBase64(), toBeHexadecimal(). All can be negated with not.
expect('[email protected]')->toBeEmail();
expect('01ARZ3NDEKTSV4RRFFQ69G5FAV')->toBeUlid();
expect('192.168.1.1')->toBeIpAddress();
expect('00:1a:2b:3c:4d:5e')->toBeMacAddress();
expect('example.com')->toBeHostname();
expect('example.co.uk')->toBeDomain();
expect('Zm9vYmFy')->toBeBase64();
expect('deadbeef')->toBeHexadecimal();All assertions support the not modifier for negation.
PHP 8.4 and PHPUnit 13 Requirement
Pest 5 requires PHP ≥ 8.4 and is built on PHPUnit 13, giving you access to the latest language and testing framework features.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
