ตอนเขียนโพสต์นี้ (เมษายน 2024) ผมยังใช้ PHPUnit ทำ unit test กับ feature test ใน Laravel เป็นหลัก พอได้เริ่มโปรเจกต์ Laravel ใหม่เลยลองเปลี่ยนมาใช้ Pest ดู ตอนนี้ผมใช้ Pest ทุกโปรเจกต์แล้ว
ช่วงนั้นผมเจอคลิปที่ Nuno Maduro คนสร้าง Pest ขึ้นเวที Laracon AU 2023 เล่าว่า Pest 2 มีอะไรใหม่ โพสต์นี้สรุปจากคลิปนั้น
Test ใน Pest สั้นกว่า PHPUnit มาก
Pest ตัดเรื่องประกาศ class กับ method ออกไป เหลือแค่ฟังก์ชัน test() หรือ it() กับ expect() ที่ต่อ assertion กันเป็นสาย ผลใน terminal ก็อ่านง่ายกว่า PHPUnit มาก
test('basic', function () {
$value = 'Laracon AU 2023';
expect($value)
->toBeString()
->not->toBeInt()
->toContain('Laracon');
});
ซ้ายคือ test ที่เขียนด้วย test() กับ expect() ขวาคือผลจาก ./vendor/bin/pest ที่บอกแค่ PASS ชื่อ test และเวลาที่ใช้
Architecture Testing กัน dd() กับ dump() หลุดขึ้น production
Pest 2 เพิ่ม architecture testing เข้ามา เราเขียนกฎของโค้ดทั้งโปรเจกต์ไว้เป็น test ได้ เช่น ห้ามมี dd() หรือ dump() ค้างอยู่ในโค้ด ถ้าใครเผลอทิ้งไว้ test จะ fail แล้วชี้ให้เลยว่าอยู่ไฟล์ไหน บรรทัดไหน
arch('globals')
->expect(['dd', 'dump'])
->not->toBeUsed();
บนเวที Nuno เขียนเป็น test('globals') ตาม Pest 2.0 ตอนนั้น รุ่นหลังใช้ arch() แทน ส่วน terminal ชี้ไปที่ dd() ใน UserController บรรทัด 21
ตั้งแต่ Pest 3 เราไม่ต้องไล่ใส่ชื่อฟังก์ชันเองแล้ว ใช้ preset ได้เลย php() กันฟังก์ชันอย่าง dump, var_dump และ die ส่วน laravel() กัน dd, env และ exit ด้วย แต่ preset นี้เช็กชื่อ class กับ method ของ controller ด้วย โปรเจกต์เดิมอาจ fail หลายข้อตอนเปิดใช้ครั้งแรก
arch()->preset()->php();
arch()->preset()->laravel();
Stress Test ยิงโหลดใส่เว็บด้วย Stressless
Nuno โชว์ plugin ชื่อ Stressless ไว้ยิง request ใส่เว็บ เพื่อดูว่า server รับโหลดได้แค่ไหน เบื้องหลังใช้ k6 ซึ่ง plugin ดาวน์โหลดมาให้เองตอนรันครั้งแรก
composer require pestphp/pest-plugin-stressless --dev
./vendor/bin/pest stress example.com --duration=10 --concurrency=5
ค่าที่เราใส่ได้มีประมาณนี้
- URL ของเว็บที่จะทดสอบ ไม่จำเป็นต้องเป็นเว็บ Laravel
--durationระยะเวลาที่ยิง ค่าเริ่มต้น 5 วินาที--concurrencyจำนวน request ที่ยิงพร้อมกัน ค่าเริ่มต้น 1
พอรันจบ Stressless จะสรุปผลให้
- Success Rate คือ request ที่สำเร็จกี่เปอร์เซ็นต์
- จำนวน request ทั้งหมด และกี่ request ต่อวินาที
- เวลาของแต่ละ request แยกเป็น DNS lookup, TLS handshake, TTFB และดาวน์โหลด

ยิง 5 วินาทีด้วย concurrency 1 ได้ 74 request สำเร็จ 100% เฉลี่ยราว 63 ms ต่อ request
ในคลิป Nuno ลองยิงแอป Laravel ที่รันบน Laravel Octane ด้วย ตัวเลขที่ได้น่าสนใจมาก ลองดูช่วงนั้นในคลิปได้ ส่วนเรื่อง Stressless แบบละเอียด Nuno ทำแยกไว้อีกคลิป
คำสั่งที่มากับ Pest 2 ยังใช้ได้ใน Pest 5
บนเวที Nuno ไม่ได้พูดถึงทุกเรื่อง ในประกาศ Pest 2 ยังมีคำสั่งอื่นอีก เทียบกับ CLI reference ของ Pest 5 แล้ว ทุกตัวยังใช้ได้เหมือนเดิม
| คำสั่ง | ทำอะไร |
|---|---|
--parallel |
รัน test พร้อมกันหลาย process ไม่ต้องติดตั้ง plugin แยกแล้ว |
--profile |
แสดง 10 test ที่ช้าที่สุด |
--retry |
รัน test ที่ไม่ผ่านรอบก่อนขึ้นก่อน แล้วหยุดทันทีที่เจอตัวที่ fail |
--dirty |
รันเฉพาะ test ที่ Git บอกว่ายังไม่ได้ commit |
--bail |
หยุดทันทีที่มี test ไม่ผ่าน |
--compact |
แสดงเฉพาะ test ที่ไม่ผ่าน |
todo() |
จด test ที่ยังไม่ได้เขียนไว้ก่อน แล้วดูรายการด้วย --todos |
--profile กับ --retry ใช้คู่กับ --parallel ไม่ได้ Pest จะแจ้ง error ทันที
todo('ส่งอีเมลยืนยันหลังสมัครสมาชิก');
แล้วสั่งรันจาก terminal
./vendor/bin/pest --parallel
./vendor/bin/pest --todos
เดโมเต็ม ๆ ดูได้ในคลิปของ Nuno ด้านบน ส่วนรายละเอียดของแต่ละฟีเจอร์อยู่ในเอกสารของ Pest






