Working with Pest in Laravel Zero

Published in Laravel Zero, Pest, PHP on Sep 1, 2020

Pest is a progressive PHP testing framework by Nuno Maduro. Behind the scenes it uses PHPUnit, and it provides an expressive, enjoyable syntax for writing tests. Pest is similar to the JavaScript Jest framework in the way that it is written.

For reference, the Laravel Zero 8 framework test suite was updated to use Pest.
See the following PRs for details on the changes: #400#403.

Installation

Pest is very quick to get started with for Laravel Zero 8 by following the installation documentation (it is the default test framework from v8.1.0). Note that Pest requires PHP 7.3 or later, and PHPUnit 9.3, which are the defaults in Laravel Zero 8.

If you are wanting to use Pest in an existing project, you can install it with the following command:

$ composer remove phpunit/phpunit --dev && composer require pestphp/pest --dev

The Pest component provides access to all the Pest commands including test and dataset generation listed below.

  • Set up Pest defaults after the initial install:
    php <application> pest:install
  • Generate a new feature test:
    php <application> pest:test [name]
  • Generate a new unit test:
    php <application> pest:test --unit [name]
  • Generate a new dataset:
    php <application> pest:dataset [name]

Once Pest has been installed, your existing tests can be run with ./vendor/bin/pest (or .\vendor\bin\pest on Windows).

If you don't want to use the install command, it's worth manually creating a tests/Pest.php file and adding a uses() statement. This will usually be to extend your Tests\TestCase class as follows:

uses(Tests\TestCase::class)->in(__DIR__);

Helper functions

Pest allows for a feature known as "helpers", these are useful functions that are saved in the tests/Helpers.php file. Here are two useful helpers for working in Laravel Zero that wrap methods on the TestCase:

if (! function_exists('assertCommandCalled')) {
    function assertCommandCalled(string $command, array $arguments = []): void
    {
        test()->assertCommandCalled($command, $arguments);
    }
}

if (! function_exists('assertCommandNotCalled')) {
    function assertCommandCalled(string $command, array $arguments = []): void
    {
        test()->assertCommandNotCalled($command, $arguments);
    }
}

In Pest 0.3 and later, all global helpers can be called on the instance as a method for higher-order tests.

Writing tests

The best way to learn about writing tests in Pest is from the documentation, but for a quick overview you can create tests as follows:

// Normal test syntax
test('it can assert true is true', function () {
   expect(true)->toBeTrue();
});

// Higher order test syntax
test('it can assert true is true in higher order syntax')->assertTrue(true);

Console output

Pest provides a clean output when you run your test suite as shown below.

Example Pest test output

When a test passes successfully, Pest will output a tick next to the test name. When a test fails, it will display a cross, and thanks to Collision the error message and a stack trace of where the error was thrown will be shown at the bottom of the test output. This allows quick debugging of tests and makes it much faster to find what is failing in a test.

Final remarks

As Pest is a "progressive" testing framework, its tests can be executed alongside class-based PHPUnit tests. This is great for situations where you are transitioning to the Pest syntax, or if you only want a subset of your tests to use the Pest syntax.

0
0
0
0