PHPUnit adalah kerangka pengujian yang menyertai setiap proyek Laravel sejak proyek itu dibuat, sedangkan Pest adalah lapisan penulisan tes yang dibangun di atas mesin PHPUnit. Topik ini membandingkan kedua gaya penulisan tes, menunjukkan satu perilaku yang sama dalam dua bentuk berkas, kemudian membahas dua perintah untuk menjalankan test suite, yaitu php artisan test dan vendor/bin/phpunit, beserta opsi penyaringan yang lazim digunakan. Seluruh contoh dijalankan pada aplikasi catatan dengan PHPUnit 12 yang terpasang sebagai dependensi bawaan Laravel.
Dua gaya penulisan tes#
Gaya PHPUnit menulis tes sebagai kelas. Satu kelas tes mewarisi TestCase, setiap kasusnya berupa metode yang berawalan test, dan setiap pernyataan berupa panggilan asersi seperti $this->assertSame(). Gaya Pest menulis tes sebagai pemanggilan fungsi global it() atau test() yang menerima nama kasus dalam bentuk kalimat bebas beserta fungsi penutup (callback), sedangkan asersinya menggunakan API expect() seperti expect($nilai)->toBe(2). Kedua gaya menguji kode yang sama dengan hasil yang sama, sehingga perbedaannya sepenuhnya terletak pada bentuk tulisannya.
Contoh pada topik ini memeriksa satu perilaku sederhana, yaitu atribut judul pada model Note mengikuti nilai yang diberikan melalui factory-nya. Berkas berikut ditulis dengan gaya PHPUnit, ditempatkan pada tests/Unit, kemudian dijalankan dengan penyaringan nama kelasnya.
# menyiapkan berkas tes gaya PHPUnit lalu menjalankannya
cd ~/aplikasi-catatan
cat > tests/Unit/JudulCatatanTest.php <<'PHP'
<?php
namespace Tests\Unit;
use App\Models\Note;
use Tests\TestCase;
class JudulCatatanTest extends TestCase
{
public function test_judul_catatan_mengikuti_nilai_yang_diberikan(): void
{
$catatan = Note::factory()->make(['judul' => 'Laporan harian']);
$this->assertSame('Laporan harian', $catatan->judul);
}
}
PHP
php artisan test --filter=JudulCatatanTest | grep -E "PASS|Tests:" PASS Tests\Unit\JudulCatatanTest
Tests: 1 passed (1 assertions)Keluaran tersebut menunjukkan satu kasus lulus dengan satu asersi. Baris PASS menyebut kelas yang diuji, sedangkan baris Tests: merangkum jumlah kasus dan jumlah asersi yang berjalan. Metode make() pada factory hanya menyusun objek model di memori tanpa menyentuh database, sehingga kasus ini tidak membutuhkan migrasi apa pun.
Perilaku yang sama ditulis dengan gaya Pest seperti berikut. Paket Pest tidak terpasang pada lingkungan contoh, sehingga blok ini hanya ilustrasi bentuk dan tidak dieksekusi.
// tidak-dijalankan
<?php
use App\Models\Note;
it('judul catatan mengikuti nilai yang diberikan', function () {
$catatan = Note::factory()->make(['judul' => 'Laporan harian']);
expect($catatan->judul)->toBe('Laporan harian');
});Tabel berikut merangkum perbedaan kedua gaya pada aspek-aspek yang paling sering menyentuh pekerjaan sehari-hari.
| Aspek | PHPUnit | Pest |
|---|---|---|
| Bentuk berkas | Kelas dengan nama berkas berakhiran Test.php | Fungsi it() atau test() pada berkas PHP biasa |
| Penamaan kasus | Nama metode diawali test_ | Kalimat bebas sebagai argumen pertama it() |
| Gaya asersi | $this->assertSame(), $this->assertTrue() | expect($nilai)->toBe(), ->toBeTrue() |
| Pemasangan | Bawaan proyek Laravel | composer require pestphp/pest beserta pluginnya |
| Hubungan dengan mesin | Menjadi mesinnya sendiri | Memanggil PHPUnit di balik layar |
Kedudukan kedua bentuk berkas tes terhadap mesin PHPUnit dirangkum pada diagram berikut.
Menjalankan test suite#
Test suite dijalankan melalui dua perintah yang membaca konfigurasi yang sama. Perintah php artisan test adalah pembungkus (wrapper) yang menyiapkan lingkungan dari phpunit.xml, lalu menampilkan keluaran berwarna dengan status per kelas tes. Perintah vendor/bin/phpunit memanggil PHPUnit secara langsung dengan bentuk keluaran aslinya, yaitu deretan titik per kasus beserta rekap akhirnya. Keduanya mengeksekusi dua suite yang dideklarasikan pada phpunit.xml, yaitu Unit untuk berkas di tests/Unit dan Feature untuk berkas di tests/Feature.
Perintah berikut menjalankan seluruh test suite aplikasi catatan.
# tidak-dijalankan
# menjalankan seluruh test suite aplikasi catatan
cd ~/aplikasi-catatan
php artisan testKeluaran berikut dicatat dari eksekusi nyata ketika direktori tests memuat lima berkas tes, dua pada tests/Unit dan tiga pada tests/Feature. Angka pada baris Tests: bergantung pada jumlah berkas tes yang ada, sehingga nilainya dapat berbeda pada proyek lain.
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Unit\JudulCatatanTest
✓ judul catatan mengikuti nilai yang diberikan 0.07s
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response 0.02s
PASS Tests\Feature\PengingatCatatanTest
✓ notifikasi pengingat terkirim ke dua kanal 0.06s
PASS Tests\Feature\PengirimanSuratTest
✓ surat ringkasan terkirim ke alamat tujuan 0.01s
Tests: 5 passed (5 assertions)
Duration: 0.23sPemanggilan langsung ke PHPUnit terlihat seperti berikut. Baris pertamanya memuat versi PHPUnit yang dipasang Composer, sedangkan baris OK merangkum jumlah kasus dan jumlah asersi yang lulus.
# memanggil PHPUnit langsung untuk satu kelas tes
cd ~/aplikasi-catatan
vendor/bin/phpunit --colors=never --filter=JudulCatatanTest | grep -E "PHPUnit|^OK"PHPUnit 12.5.43 by Sebastian Bergmann and contributors.
OK (1 test, 1 assertion)Empat opsi berikut paling sering digunakan saat bekerja dengan test suite. Opsi --filter menjalankan kasus yang namanya cocok dengan pola yang diberikan, misalnya php artisan test --filter=JudulCatatanTest. Opsi --testsuite membatasi eksekusi pada satu suite, misalnya --testsuite=Unit. Opsi --stop-on-failure menghentikan eksekusi pada kegagalan pertama sehingga pesannya dapat diperiksa segera, sedangkan opsi --parallel menjalankan suite dalam beberapa proses untuk memangkas durasi setelah paket ParaTest dipasang. Ketiga opsi pertama berlaku baik pada php artisan test maupun vendor/bin/phpunit, sedangkan --parallel merupakan fitur tambahan pembungkus php artisan test.
Kesalahan umum#
Kesalahan pertama adalah menulis fungsi it() sebelum paket Pest dipasang. PHPUnit memuat berkas tes tersebut sebagai berkas PHP biasa, tidak menemukan fungsi yang dipanggilnya, lalu berhenti dengan pesan Call to undefined function it() yang menyebut baris pemanggilannya. Perbaikannya adalah memasang Pest terlebih dahulu melalui Composer, atau menulis kasus tersebut dengan gaya PHPUnit selama Pest belum terpasang.
Kesalahan kedua adalah memberi nama berkas atau metode yang tidak mengikuti konvensi. PHPUnit hanya memperlakukan berkas yang namanya berakhiran Test.php sebagai berkas tes, dan hanya metode yang diawali test yang dijalankan sebagai kasus. Kelas pada berkas JudulCatatan.php atau metode cekJudul() tidak memunculkan error apa pun, tetapi juga tidak pernah dieksekusi, sehingga suite tampak hijau padahal kasusnya tidak diuji. Ikuti konvensi penamaan pada kedua tingkat tersebut.
Kesalahan ketiga adalah menganggap kedua perintah tadi sebagai dua alat yang berbeda sehingga hasilnya dapat berbeda. Keduanya membaca phpunit.xml yang sama, memuat suite yang sama, dan menjalankan kasus yang sama, sehingga pilihannya sepenuhnya menyangkut bentuk keluaran dan fitur tambahan seperti --parallel. Perbedaan angka pada proyek yang sama biasanya berasal dari berkas tes yang berubah sejak eksekusi sebelumnya, bukan dari pilihan perintahnya.
Ringkasan#
- Gaya PHPUnit menulis tes sebagai kelas dengan metode berawalan
testdan asersi$this->assert*(), sedangkan gaya Pest menulisnya sebagai fungsiit()dengan asersiexpect(). - Pest menjalankan mesin PHPUnit di balik layar, sehingga kedua gaya dapat berdampingan dalam satu suite dan migrasinya dapat dilakukan bertahap.
php artisan testdanvendor/bin/phpunitmembacaphpunit.xmlyang sama dan menguji suite yang sama, dengan perbedaan pada bentuk keluaran serta opsi--filter,--testsuite,--stop-on-failure, dan--parallel.
Referensi#
- Testing: Getting Started — Laravel
— Dokumentasi pengujian Laravel, mencakup pembuatan berkas tes dan perintah
php artisan test. - Artisan Console — Laravel
— Daftar perintah Artisan beserta opsinya, termasuk perintah
test. - PHPUnit 12.1 Manual — PHPUnit — Manual PHPUnit untuk penulisan dan eksekusi tes gaya kelas.
- Installation — Pest — Dokumentasi pemasangan Pest dan keterkaitannya dengan PHPUnit.