Pest PHP Nedir ve Neden Tercih Edilir?
Pest, PHP için yazılmış, PHPUnit üzerine inşa edilmiş bir test framework'üdür. PHPUnit'in tüm yeteneklerini korurken üzerine daha okunabilir bir sözdizimi ekler. Mevcut PHPUnit testlerinizle birlikte çalışabilir; Pest'i kademeli olarak benimseyebilirsiniz.
Temel fark, test yazım biçimindedir. PHPUnit'te sınıf tanımlar, metotlar yazarsınız. Pest'te ise fonksiyonlar ve it()/test() gibi yardımcı fonksiyonlarla daha az kod ile aynı işi yaparsınız. Bu, özellikle davranış odaklı test isimlendirmesini kolaylaştırır.
Önkoşullar
- PHP 8.1 veya üzeri (Pest'in güncel sürümleri PHP 8.1+ gerektirir; kurulum öncesi Pest dokümantasyonundan hedeflediğiniz sürümün PHP gereksinimini doğrulayın).
- Composer kurulu olmalı.
- Test edilecek proje Composer ile bağımlılık yönetiyor olmalı.
Sürüm kapsamı: Bu rehberdeki örnekler Pest 3.x dönemindeki API'yi varsayar. Pest sürümleri arasında bazı yardımcı fonksiyonlar ve yapılandırma anahtarları değişebildiği için, kurduğunuz sürümün dokümantasyonunu esas alın.
Kurulum
Projeye geliştirme bağımlılığı olarak Pest ve eklentisini ekleyin:
composer require pestphp/pest --dev --with-all-dependencies
composer require pestphp/pest-plugin-laravel --dev # Laravel kullanıyorsanız
Ardından başlatma komutunu çalıştırın:
./vendor/bin/pest --init
Bu komut tests/Pest.php dosyasını ve gerekli yapılandırmayı oluşturur. Laravel projelerinde tests/Pest.php içinde uses() çağrılarıyla testlerin hangi temel sınıfı kullanacağını belirtirsiniz.
Test Yapısı
Pest testleri tests/ dizininde bulunur. Dosya adı *.php olabilir; ancak *Test.php gibi bir son ek kullanmak yapılandırmayı netleştirir. Bir test dosyası tipik olarak şöyle görünür:
<?php
it('iki sayıyı toplar', function () {
$result = 2 + 3;
expect($result)->toBe(5);
});
test('metni büyük harfe çevirir', function () {
expect(strtoupper('pest'))->toBe('PEST');
});
it() ve test() fonksiyonları eşdeğerdir; yalnızca okunabilirlik tercihidir. it() ile başlayan açıklamalar cümle gibi okunur.
Beklenti (Expectation) API'si
Pest'in en belirgin özelliği akıcı beklenti zinciridir:
expect($value)->toBe(10);
expect($array)->toHaveCount(3);
expect($string)->toContain('Pest');
expect($object)->toBeInstanceOf(User::class);
expect(fn () => riskyOperation())->toThrow(Exception::class);
toBe() katı eşitlik (===) kullanır; toEqual() ise gevşek karşılaştırma yapar. Bu ayrımı bilmek, tip farklılıklarından kaynaklanan yanıltıcı test sonuçlarını önler.
Yaşam Döngüsü Kancaları
Her testten önce veya sonra çalışacak kod için beforeEach ve afterEach kullanılır:
beforeEach(function () {
$this->user = new User(['name' => 'Test']);
});
afterEach(function () {
// temizlik işlemleri
});
it('kullanıcı adını döner', function () {
expect($this->user->name)->toBe('Test');
});
Tüm dosya için bir kez çalışacak kurulum için beforeAll ve afterAll mevcuttur. Bu kancaların dosya kapsamında çalıştığını unutmayın; testler arası paylaşılan durum, testlerin sırasına bağımlılık yaratabilir.
Veri Sağlayıcıları (Datasets)
Aynı testi farklı girdilerle çalıştırmak için dataset kullanılır:
it('sayıları toplar', function (int $a, int $b, int $expected) {
expect($a + $b)->toBe($expected);
})->with([
[1, 2, 3],
[0, 0, 0],
[-1, 1, 0],
]);
İsimlendirilmiş dataset tanımlayarak hata çıktısını daha okunur hale getirebilirsiniz:
dataset('toplama', [
'pozitif sayılar' => [1, 2, 3],
'sıfırlar' => [0, 0, 0],
]);
it('sayıları toplar', function (int $a, int $b, int $expected) {
expect($a + $b)->toBe($expected);
})->with('toplama');
Gruplama
İlgili testleri describe() ile gruplayabilirsiniz:
describe('Kullanıcı işlemleri', function () {
it('oluşturulabilir', function () {
// ...
});
it('silinebilir', function () {
// ...
});
});
Mock ve Stub
Pest, PHPUnit'in mock altyapısını kullanır. Ancak daha okunabilir bir yol için Mockery entegrasyonu (Pest eklentisiyle) tercih edilebilir:
it('servisi çağırır', function () {
$mock = Mockery::mock(PaymentGateway::class);
$mock->shouldReceive('charge')->once()->andReturn(true);
$service = new OrderService($mock);
expect($service->process())->toBeTrue();
});
Mock kullanırken dikkat edilmesi gereken nokta, gerçek davranışı değil, etkileşimi test ettiğinizdir. Aşırı mock kullanımı testleri kırılgan hale getirir.
Kapsam (Coverage)
Kod kapsamı raporu için Xdebug veya PCOV gerekir. Kurulum sonrası:
./vendor/bin/pest --coverage
Kapsam yüzdesi tek başına kalite göstergesi değildir; yüksek kapsam, testlerin anlamlı olduğu anlamına gelmez.
Yaygın Hatalar
- Testler arası durum paylaşımı: Global değişkenler veya statik özellikler testleri sıraya bağımlı hale getirir. Her test kendi verisini kurmalı.
toBeiletoEqualkarıştırmak: Tip farkları nedeniyle beklenmedik başarısızlıklar ya da yanlış geçen testler oluşur.- Gerçek ağ/veritabanı çağrıları: Testler yavaşlar ve dış sistemlere bağımlı hale gelir. Bunları izole edin.
- Aşırı mock: Uygulama kodundaki değişiklikler testleri gereksiz yere kırar.
Güvenlik Notları
Test ortamında kullanılan kimlik bilgileri ve API anahtarları üretim ortamından ayrı olmalı. Test konfigürasyon dosyalarında (phpunit.xml, .env.testing gibi) gerçek sırlar bulundurmayın. Testlerin üretim veritabanına bağlanması, yanlışlıkla veri silinmesine yol açabilir; ortam ayrımını zorunlu tutun.
Sonuç
Pest, PHPUnit'in yeteneklerini koruyarak test yazımını kısaltır ve okunabilirliği artırır. Mevcut PHPUnit testleriyle birlikte çalışabildiği için geçiş kademeli yapılabilir. Testlerinizin değeri, satır sayısından veya kapsam yüzdesinden değil, gerçek davranışı doğru biçimde doğrulamasından gelir.