Testing is an essential part of the software development process. It helps ensure that our code works as expected and catches any potential bugs or issues before they make their way to production. In the world of PHP & Laravel, PHPUnit has been the go-to testing framework for many years. However, recently a new contender has emerged - Pest. In this blog post, we will explore Pest, discuss how we migrated to it in under 30 minutes, and how you can as well.
Introducing Pest
Pest is a delightful testing framework for PHP that aims to provide a more enjoyable testing experience.
One of the main goals of Pest is to make tests more readable and expressive. It achieves this by leveraging PHP's anonymous classes and closures, allowing you to write tests in a more natural language-like syntax. If you’ve ever used RSpec with Ruby or Jest with Javascript, the syntax should very familiar.
it('can be an example', function () {
expect('example')->toBe('example');
});
Pest also comes with some additional features that enhance the testing experience. It includes parallel testing support out of the box, making it faster than PHPUnit in certain scenarios. It also provides a beautiful test runner interface that displays test results in an easy-to-read format.
Migrating from PHPUnit to Pest
If you've been using PHPUnit for your Laravel projects and want to give Pest a try, migrating your existing code base is easy. We completed the install steps, migration & validation in under 3o minutes.
First, you'll need to install Pest using Composer:
composer require pestphp/pest --dev
Once installed, you can start writing tests using Pest alongside your existing PHPUnit tests. Pest provides a compatibility layer that allows both frameworks to coexist within the same project.
To migrate your existing tests from PHPUnit to Pest, you can simply copy them over and update the syntax where necessary. For example, here's how a basic test written in PHPUnit would look in Pest:
// PHPUnit
public function testExample()
{
$this->assertTrue(true);
}
// Pest
it('should pass the example test', function () {
expect(true)->toBeTrue();
});
As you can see, the syntax in Pest is more expressive and resembles natural language. The expect
function is used to make assertions, and the it
function is used to define a test.
Pest also provides additional helper functions that make testing even more readable. For example, you can use the assertEquals
function to compare two values:
// PHPUnit
$this->assertEquals(10, $result);
// Pest
expect($result)->toEqual(10);
Laravel Integration

Pest’s expectations take the place of the base PHPUnit assertions however it does not come with support for features such as Laravel HTTP Request testing by default. To gain access to these you will have to install a plugin by running the following code:
composer require pestphp/pest-plugin-laravel --dev
You can use the plugins HTTP methods in place of the Laravel HTTP Request functions.
Before:
$this->get('/index')->assertStatus(400)
After:
get('/index')->assertStatus(400)
Note that you will have to ensure you have access to these functions, one possible method:
use function PestLaravel{get,post};
Automatic Migration
If you have a large codebase with lots of tests, then manually migrating your tests may be a task thats not feasible for you. It is possible to run PHPUnit tests alongside Pest style tests. However, it is important to note that this approach may introduce confusion and complexity, especially for new developers joining the project.
Luckily, there is a simple solution, Pest provides a plugin that can automatically convert your PHPUnit tests to the Pest style. Simply run the following:
composer require pestphp/pest-plugin-drift --dev
./vendor/bin/pest --drift
This process should leave you with a fully converted test suite, however due to chance of the plugin not being able to migrate something a summary is provided at the end of this process that will let you know if any tests failed to be converted. Since there shouldn’t be many of these ( in our case there weren’t any ) manual migration should not take much time.
One thing to note is that the extensions brought in by the Laravel Pest plugin will not be used in the migration, this means you will have to migrate these manually if you want to, however the tests will work without this step.
One thing that you might want to look out for is the base TestCase that is used, if you had overwritten the default test case class with your own, ensure that you specify this in Pest.php, as shown below:
uses(TestsTestCase::class)->in('Feature', 'Unit');
This will bind the $this
variable within your tests to your custom TestCase, rather than the default one, this should be done automatically in the migration but in our case, it seems that it did not work.

Our Recommendations

We recommend that when migrating to Pest that you use some form of version control to ensure that you can roll back your changes easily if something goes wrong. You should also run a full test report both before and after migrating, this will let you make sure that the migration was a success and help you avoid any nasty surprises.
Conclusion
In conclusion, Pest offers a fresh and enjoyable approach to testing in Laravel. Its expressive syntax and additional features make writing tests a breeze. Migrating your code base from PHPUnit to Pest is relatively straightforward and can greatly enhance your testing experience. So why not give Pest a try and see how it can level up your Laravel testing game? Happy testing!
If you would like assistance with your existing Laravel App from an experienced, professional team - Contact FONSEKA and they will get it up to speed, inclusive of the latest testing setup.
You can learn more about Pest here:
For more information about completing the migration visit: