I started learning pure PHP in the middle of 2015. Then, I got familiar with CodeIgniter 3 and Laravel 5.1. Through the years, Laravel is my framework of choice, and I'm still sticking with it. Such as other popular PHP projects, I see PHPUnit is the only choice for unit testing. But there was a little change in 2021 when Pest came. It's created by Nuno Maduro - an engineer at Laravel, who also makes lots of great projects/packages widely used in PHP and Laravel community.
Since the very first day of Pest, I haven't cared about it because PHPUnit is enough for me and I feel lazy to learn this new test tool. But the more Laravel community grows, the more Pest is recommended. Many Laravel projects/packages from Spatie, Livewire, Filament, ... use Pest. So the problem is when testing things related to them, I have to port to PHPUnit. I seem to have no choice. It's time for me to take a look at Pest.
The first look
Following the installation section, I create my first PHP project using Pest.
mkdir ~/Herd/lerning-pest
cd ~/Herd/learning-pest
composer require pestphp/pest --dev --with-all-dependencies
./vendor/bin/pest --init
The directory structure is almost the same as PHPUnit. The different thing is how a test looks. It's closure-based instead of class-based.
<?php
// tests/Unit/ExampleTest.php
test('example', function () {
expect(true)->toBeTrue();
});
I know using Closure that can lazily attach methods to an object in runtime. So this may be re-written in PHPUnit like that.
<?php
// tests/Unit/ExampleTest.php
class ExampleTest extends \PHPUnit\Framework\TestCase
{
public function test_example()
{
$this->assertTrue(true);
}
}
It says Pest assertion syntax is inspired by Ruby's Rspec and Jest, which I don't know. So, I'm also not too much interested in them. For me, it doesn't matter how assertion syntax is.
I just like the result displayed when running tests. It's much prettier and cleaner than PHPUnit, I think.
Assertions
These are assertions I used the most in PHPUnit.
$this->assertSame($expected, $actual);
$this->assertTrue($condition);
$this->assertFalse($condition);
$this->assertNull($actual);
$this->assertEmpty($array);
$this->assertCount($count, $countable);
$this->assertInstanceof($type, $instance);
They can be easily re-written in Pest.
expect($actual)->toBe($expected);
expect($condition)->toBeTrue();
expect($condition)->toBeFalse();
expect($actual)->toBeNull();
expect($actual)->toBeEmpty();
expect($actual)->toBeInstanceOf($type);
As I mentioned earlier, Pest assertion syntax is fine, but I'm currently sticking with PHPUnit because I don't need to study new APIs. Anyway, I prefer PHPUnit assertions and only use things that are unique in Pest. Architecture Testing is an example. My test file looks like this.
<?php
test("all PHP files in LearningPest namespace must have strict mode enabled", function () {
arch()
->expect('LearningPest')
->toUseStrictTypes();
});
test('all PHPUnit assertions are available for Pest', function () {
$instance = new \stdClass();
$getInstance = function () use ($instance) {
return $instance;
};
$this->assertSame($instance, $getInstance());
$this->assertInstanceOf(stdClass::class, $instance);
$this->assertTrue(1 < 2);
$this->assertFalse(1 > 2);
$value = null;
$this->assertNull($value);
$this->assertEmpty([]);
$array = [1, 2, 3];
$this->assertCount(3, $array);
});
Compulsory features
There are a number of compulsory features that allow me to work in Pest identically to PHPUnit. Here they are:
- PHPUnit has data provider. Pest has datasets.
- PHPUnit has
setUp
,tearDown
,setUpBeforeClass
andtearDownAfterClass
. Pest hasbeforeEach
,afterEach
,beforeAll
andafterAll
. - Both have exception checks and can skip/group/filter tests.
Mockery is a standalone library, so I don't list it here.
On the other hand, Pest has lots of things may come in handy such as architecture, snapshot or stress testing and plugins. I'll discover them when writing tests.
Conclusion
- Pest is built on top of PHPUnit, widely used and recommended in PHP and Laravel community recently.
- Using Pest, I can work in the nearly same way before, but with prettier CLI and more helpful features.
- Now, Pest's the default testing framework for my PHP and Laravel applications.
If you are a PHP developer who hasn't used Pest, give it a try.
Top comments (0)