Why did Pest become Laravel’s default?
Starting with Laravel 11, Pest is selected as the default test framework when you create a project withlaravel new. PHPUnit has long been the standard testing tool for PHP, but Pest builds on top of PHPUnit while offering a more concise, more readable syntax.
Because Pest runs on top of PHPUnit, your existing PHPUnit tests continue to work. You can migrate incrementally.
Main differences from PHPUnit
Test syntax
The most immediately visible difference is how tests are written.- Pest
- PHPUnit
test() function takes a closure. Because there’s no class or method definition, the test’s intent is clear from the first line. it() works the same way. Written in English, it('can login', ...) reads as a natural sentence.
The expect() API
Pest’s headline feature is chained assertions via expect().
expect($value)->toBe(), ->toBeNull(), ->toContain(), and ->toHaveCount() read naturally in English. You can also combine multiple assertions with method chaining.
Setup and teardown
beforeEach() corresponds to PHPUnit’s setUp(); afterEach() corresponds to tearDown().
Datasets — table-driven tests
Usedataset to run the same test logic against multiple sets of input.
'no email') is appended to the test name, so it’s obvious at a glance which pattern failed.
arch() tests — automated architecture checks
Pest’s arch() tests verify the structure of your codebase. You can automatically check architecture rules like “controllers must not depend directly on models” or “models must extend Eloquent.”
laravel() preset verifies model naming, controller inheritance, middleware structure, and other common Laravel conventions in one go.
Practical example in a Laravel project
Creating tests
Using Laravel test helpers as-is
Because Pest extends Laravel’sTestCase, all Laravel test helpers—actingAs(), assertDatabaseHas(), HTTP test helpers, etc.—work as usual.
Factories and database transactions
Traits likeRefreshDatabase and DatabaseTransactions can also be applied easily with uses(). Writing this at the top of a file applies it to the whole file.
tests/Pest.php automatically enables RefreshDatabase for all Feature tests. You can also override it in individual test files.
Coexisting with existing PHPUnit tests
Pest and PHPUnit can coexist in the same project. You don’t have to rewrite existing PHPUnit tests—just start writing new tests in Pest style.Since Laravel 11, if Pest is installed,
php artisan test automatically runs via Pest.How to approach migration
- First add
uses()configuration totests/Pest.php - Write new tests in Pest style
- Migrate existing PHPUnit tests gradually while verifying behavior
Summary
Pest isn’t a replacement for PHPUnit but a higher layer wrapping PHPUnit. Its Laravel integration is deep enough that it’s the default at starter kit generation time. The adoption cost for existing projects is low, and you can start reaping the benefits by writing just new tests in Pest.
The more tests you write, the sooner bugs are caught and the lower the psychological barrier to refactoring. Pest is a tool for reducing “the friction of writing tests themselves.”
Pest official docs
See the official documentation for all Pest features, including datasets, coverage, and parallel execution.