Pest 為何成為 Laravel 的預設
自 Laravel 11 起,用laravel new 建立專案時 Pest 就成為預設的測試框架。PHPUnit 長期以來是 PHP 標準測試工具,但 Pest 以 PHPUnit 為基礎,提供更簡潔易讀的測試寫法。
Pest 執行於 PHPUnit 之上,既有的 PHPUnit 測試可原樣執行,遷移可循序進行。
與 PHPUnit 的主要差異
測試寫法
最直觀的差異就是寫法。- Pest
- PHPUnit
test() 函式接收 closure。因為不需定義類別或方法,測試的意圖從第一行就清楚。it() 用法相同。以英文書寫時可讀為 it('can login', ...) 這樣自然的句子。
expect() API
Pest 最大特色是用 expect() 的鏈式斷言。
expect($value)->toBe()、->toBeNull()、->toContain()、->toHaveCount() 等以近似英文自然句的形式寫斷言。多個斷言可用方法鏈組合起來。
Setup 與 Teardown
PHPUnit 的setUp() 對應 beforeEach(),tearDown() 對應 afterEach()。
Dataset — 表格式驅動測試
若要以多筆資料執行同一測試邏輯,可用dataset。
'沒有 email')會出現在測試名稱上,能一眼看出是哪個模式失敗。
arch() 測試 — 自動檢查架構
Pest 的 arch() 是驗證程式碼庫結構的測試。像「Controller 是否直接依賴 Model」「Model 是否繼承 Eloquent」這類架構規則能自動驗證。
laravel() 預設集會依 Laravel 一般慣例驗證 Model 命名、Controller 繼承、Middleware 結構等。
Laravel 專案的實務範例
建立測試
直接使用 Laravel 的測試 helper
Pest 繼承自 Laravel 的TestCase,因此 actingAs()、assertDatabaseHas()、HTTP 測試 helper 等所有 Laravel 測試 helper 都可以直接使用。
Factory 與資料庫交易
RefreshDatabase 或 DatabaseTransactions trait 也能透過 uses() 輕鬆套用。寫在檔案開頭就會套用整份檔案。
tests/Pest.php 設定一次後,所有 Feature 測試就會自動啟用 RefreshDatabase,也可於個別測試檔覆寫。
與既有 PHPUnit 測試共存
Pest 與 PHPUnit 可以在同一專案共存。既有 PHPUnit 測試不必改寫,只要新測試用 Pest 格式書寫即可。自 Laravel 11 起,
php artisan test 若已安裝 Pest 會自動用 Pest 執行。遷移步驟
- 首先於
tests/Pest.php加上uses()設定 - 新加的測試以 Pest 格式書寫
- 既有 PHPUnit 測試邊確認邊逐步遷移
總結
Pest 不是 PHPUnit 的替代品,而是包在 PHPUnit 上的上層。與 Laravel 整合深入,甚至在啟動套件產生時就作為預設選項。導入既有專案成本低,只要從新測試開始試就能享受其好處。
當測試量增加時,能更快發現 bug,重構的心理阻力也降低。Pest 就是為了減少「撰寫測試本身的摩擦」而生的工具。
Pest 官方文件
Dataset、覆蓋率、平行執行等 Pest 完整功能,請參考官方文件。