为什么 Pest 成为 Laravel 的默认
从 Laravel 11 开始,用laravel new 创建项目时会默认选择 Pest 作为测试框架。PHPUnit 长期以来是 PHP 事实上的标准测试工具,而 Pest 在 PHPUnit 之上提供了更简洁、更易读的测试写法。
Pest 运行在 PHPUnit 之上,现有的 PHPUnit 测试可以直接运行,可以按阶段迁移。
与 PHPUnit 的主要差异
测试写法
最直观的差异就是测试的写法。- Pest
- PHPUnit
test() 函数接收一个闭包。不需要类和方法定义,从第一行就能看清测试的意图。it() 也一样。用英语写时 it('can login', ...) 也能作为自然的英语句读。
expect() API
Pest 最鲜明的特点是基于 expect() 的链式断言。
expect($value)->toBe()、->toBeNull()、->toContain()、->toHaveCount() 等断言像英文一样自然。也可以用方法链把多条断言串到一起。
setup 与 teardown
PHPUnit 里的setUp() 对应 Pest 的 beforeEach(),tearDown() 对应 afterEach()。
数据集 —— 表格驱动测试
想用多组数据跑同一段测试逻辑时,用dataset。
'空邮箱')会附在测试名上,一眼就能看出是哪个模式失败了。
arch() 测试 —— 架构自动校验
Pest 的 arch() 用来验证代码库的结构。可以自动检查“控制器有没有直接依赖模型?”、“模型是不是继承了 Eloquent?”这类架构规则。
laravel() 预设集中了模型命名、控制器继承、中间件结构等符合 Laravel 惯例的规则。
Laravel 项目中的实践
创建测试
直接使用 Laravel 的测试辅助器
Pest 继承 Laravel 的TestCase,所以 actingAs()、assertDatabaseHas()、HTTP 测试辅助器等所有 Laravel 测试辅助器都能直接用。
工厂与数据库事务
RefreshDatabase 和 DatabaseTransactions trait 也可以通过 uses() 轻松应用。写在文件开头就作用于整个文件。
tests/Pest.php 里设置一次,所有 Feature 测试都会自动启用 RefreshDatabase。个别测试文件里也可以覆盖。
与现存 PHPUnit 测试共存
Pest 和 PHPUnit 可以在同一个项目里共存。既有的 PHPUnit 测试不用改,新的测试直接用 Pest 写就好。Laravel 11 及以后,如果安装了 Pest,
php artisan test 会自动用 Pest 来执行。迁移建议
- 先在
tests/Pest.php里配置好uses() - 新增的测试用 Pest 写法
- 既有的 PHPUnit 测试边确认行为边慢慢迁移
总结
Pest 不是 PHPUnit 的替代品,而是包裹在 PHPUnit 之上的上层框架。它与 Laravel 集成很深,启动套件生成时都默认选中它。对既有项目引入成本低,从新测试开始试用就能享受红利。
写测试的量上去后,bug 会更早被发现,重构的心理门槛也会降低。Pest 是一款专门用来降低“写测试本身的摩擦”的工具。
Pest 官方文档
Pest 的完整功能(数据集、覆盖率、并行执行等)请查看官方文档。