2 Comments

Advanced Pest setup

Pest PHP is a relatively new PHP testing framework. It has a nice syntax, and a few cool features built on top of PHPunit. I already wrote an article on how to convert a PHPunit test suite to Pest, but in this article I want to take a look at some cool Pest techniques and my Pest configuration.

The TestCase class

First of all, I want to start at the TestCase class. I haven't done something special with it, but I would like to show it anyways.

<?php

// tests/Pest.php

uses(Tests\TestCase::class)->in('Feature', 'Unit');

The RefreshDatabase trait

Because I use the RefreshDatabase in almost all of my tests, I like to configure it globally.

For tests that don't use the database, this will cost a little extra time. But it is neglectable and it doesn't outweight the advantage of not having to repeat it in every test.

<?php

// tests/Pest.php

uses(Tests\TestCase::class)->in('Feature', 'Unit');
uses(Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature', 'Unit');

Because the trait autoruns the migrations, no further actions are required to migrate the database for every test.

The WithFaker trait

Faker is a handy library to get fake testing data, such as fake names, emails and photos.

Pest has its own plugin for faker, but it requires you to import the Pest\Faker\faker function each time you want to use Faker:

use function Pest\Faker\faker;

it('has a name', function () {
    $name = faker()->word();
    $project = Project::factory()->create(['name' => $name]);
    expect($project->name)->toBe($name);
});

Instead I'd like to add the WithFaker trait in the Pest configuration file:

<?php

// tests/Pest.php

uses(Tests\TestCase::class)->in('Feature', 'Unit');
uses(Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature', 'Unit');
uses(Illuminate\Foundation\Testing\WithFaker::class)->in('Feature', 'Unit');

This way I can remove the import in the test:

use function Pest\Faker\faker;

it('has a name', function () {
    $name = faker()->word();
    $name = $this->faker->word();
    $project = Project::factory()->create(['name' => $name]);
    expect($project->name)->toBe($name);
});

The withoutExceptionHandling() method

When testing, it's common to add $this->withoutExceptionHandling() to your tests for better debugging. It will add more clear error messages.

Instead of adding it manually to every test, I like to add it globally for all my tests:

<?php

// tests/Pest.php

uses(Tests\TestCase::class)->in('Feature', 'Unit');
uses(Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature', 'Unit');
uses(Illuminate\Foundation\Testing\WithFaker::class)->in('Feature', 'Unit');
uses()->beforeEach(fn () => $this->withoutExceptionHandling())->in('Feature', 'Unit');

This way it is enabled by default, and if I want I can disable it again in a test:

it('has a name', function () {
    $this->withExceptionHandling();
    $name = $this->faker->word();
    $board = Board::factory()->create(['name' => $name]);
    expect($board->name)->toBe($name);
});

Conclusion

Some things are annoying to repeat over and over, and fortunately you can add them globally in Pest. Thanks for reading!

Share this article:

Subscribe to my newsletter

Continue reading:

Eloquent polymorphic relationships explained (with examples)

In my opinion, Eloquent is one of the most powerful features of Laravel. It is an API for interacting with your database, and it has a very nice and easy-to...

Understanding the magic of Laravel macros

Using Laravel macros is a powerful way to extend default behavior of many classes in Laravel, such as Collections, Stringables and Reponses. In this article I...

Eloquent relationships explained (with examples)

In my opinion, Eloquent is one of the most powerful features of Laravel. It is an API for interacting with your database, and it has a very nice and easy-to...

Leave a comment

Comments (2)

    Erick's avatar
    Erick Reply
    1 month ago

    This information is completely free and is so important how can I learn more

      Jeroen van Rensen's avatar
      Jeroen van Rensen
      1 month ago

      Hi Erick, I'm really happy to hear that! Thanks!