跳转到主要内容

为什么 Pest 成为 Laravel 的默认

从 Laravel 11 开始,用 laravel new 创建项目时会默认选择 Pest 作为测试框架。PHPUnit 长期以来是 PHP 事实上的标准测试工具,而 Pest 在 PHPUnit 之上提供了更简洁、更易读的测试写法。
Pest 运行在 PHPUnit 之上,现有的 PHPUnit 测试可以直接运行,可以按阶段迁移。
官方选择 Pest,背后的目标是减少写测试时的摩擦。省掉“定义类、写方法”这一套仪式化步骤,让你把注意力放在“想验证什么”本身,从而更容易养成写测试的习惯。

与 PHPUnit 的主要差异

测试写法

最直观的差异就是测试的写法。
Pest 的 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?”这类架构规则。
arch() 测试通过对源代码做静态分析来执行,不会真的发 HTTP 请求或访问数据库,速度非常快。
Pest 也提供了常用的架构规则预设。
laravel() 预设集中了模型命名、控制器继承、中间件结构等符合 Laravel 惯例的规则。

Laravel 项目中的实践

创建测试

Laravel 11 及以后按默认配置执行时,会生成 Pest 风格的测试文件。

直接使用 Laravel 的测试辅助器

Pest 继承 Laravel 的 TestCase,所以 actingAs()assertDatabaseHas()、HTTP 测试辅助器等所有 Laravel 测试辅助器都能直接用。

工厂与数据库事务

RefreshDatabaseDatabaseTransactions trait 也可以通过 uses() 轻松应用。写在文件开头就作用于整个文件。
tests/Pest.php 里设置一次,所有 Feature 测试都会自动启用 RefreshDatabase。个别测试文件里也可以覆盖。

与现存 PHPUnit 测试共存

Pest 和 PHPUnit 可以在同一个项目里共存。既有的 PHPUnit 测试不用改,新的测试直接用 Pest 写就好。
Laravel 11 及以后,如果安装了 Pest,php artisan test 会自动用 Pest 来执行。

迁移建议

  1. 先在 tests/Pest.php 里配置好 uses()
  2. 新增的测试用 Pest 写法
  3. 既有的 PHPUnit 测试边确认行为边慢慢迁移
不需要急着把所有测试都改写。Pest 的语法比 PHPUnit 学习成本低,团队接受起来也比较顺。

总结

Pest 不是 PHPUnit 的替代品,而是包裹在 PHPUnit 之上的上层框架。它与 Laravel 集成很深,启动套件生成时都默认选中它。对既有项目引入成本低,从新测试开始试用就能享受红利。 写测试的量上去后,bug 会更早被发现,重构的心理门槛也会降低。Pest 是一款专门用来降低“写测试本身的摩擦”的工具。

Pest 官方文档

Pest 的完整功能(数据集、覆盖率、并行执行等)请查看官方文档。
最后修改于 2026年7月18日