Home About Skills Products Work
Projects Services Experience
Learn
Tutorials Courses Blogs Resources
Contact
Blog · Laravel

Testing Laravel Applications with Pest

Testing Laravel Applications with Pest

Pest is a testing framework built on top of PHPUnit, designed specifically to make Laravel tests read cleanly — less boilerplate, more expressive syntax, while still running on the exact same battle-tested PHPUnit engine underneath.

Installing Pest

composer require pestphp/pest --dev --with-all-dependencies
php artisan pest:install

A Basic Test

it('returns a successful response from the homepage', function () {
    $response = $this->get('/');
    $response->assertStatus(200);
});

No class boilerplate, no public function test...() naming convention — just a plain closure and a description string that reads like a sentence.

Expectations: Pest's Readable Assertions

expect($user->name)->toBe('Bikesh');
expect($posts)->toHaveCount(5);
expect(fn() => $service->process(null))->toThrow(InvalidArgumentException::class);

These are functionally identical to PHPUnit's assertEquals/assertCount/expectException — just chainable and, most developers agree, considerably more pleasant to read back later.

Testing a Full Feature

it('creates a post when the form is valid', function () {
    $user = User::factory()->create();

    $response = $this->actingAs($user)->post('/posts', [
        'title' => 'My First Post',
        'body' => 'Some content here.',
    ]);

    $response->assertRedirect('/posts');
    $this->assertDatabaseHas('posts', ['title' => 'My First Post']);
});

Every Laravel testing helper you already know — actingAs, assertDatabaseHas, model factories — works completely unchanged; Pest is a syntax layer, not a replacement for Laravel's test tooling.

Datasets: One Test, Many Inputs

it('rejects invalid emails', function (string $email) {
    $response = $this->post('/register', ['email' => $email]);
    $response->assertSessionHasErrors('email');
})->with(['not-an-email', 'missing@domain', '@nodomain.com']);

This runs the same test body three times, once per dataset value — far less repetition than writing three nearly-identical test methods by hand.

Grouping Related Tests

describe('Post creation', function () {
    it('requires a title', function () { /* ... */ });
    it('requires a body', function () { /* ... */ });
    it('assigns the authenticated user as author', function () { /* ... */ });
});

Pest is fully compatible with existing PHPUnit test suites — you can adopt it incrementally in a project that already has hundreds of PHPUnit tests, writing new tests in Pest's syntax while the old ones keep running exactly as before.

Laravel for Beginners: Setting Up Your First Project

Laravel for Beginners: Setting Up Your First Project

A complete first-day guide to Laravel — installation, folder structure, your first route, and your first migration.

Building a REST API with Laravel: A Complete Guide

Building a REST API with Laravel: A Complete Guide

API routes, resources, Form Request validation, correct status codes, and Sanctum auth — a real, production-reasonable Laravel API.

Laravel Eloquent Relationships Explained with Real Examples

Laravel Eloquent Relationships Explained with Real Examples

One-to-many, many-to-many, polymorphic, and the N+1 query trap that catches almost every Laravel developer at least once.

Esc