Pest 测试需显式启用 Laravel 测试环境:在 tests/Pest.php 中调用 uses(Tests\TestCase::class)->in('Feature', 'Unit'),并确保 TestCase 使用 CreatesApplication;数据库需配合 RefreshDatabase trait 与 :memory: SQLite;模型工厂改用 User::factory()->create();HTTP 测试依赖正确 bootstrap 路径和路由缓存。
直接用 Pest 写 Laravel 单元测试,比原生 PHPUnit 更轻、更直观,但前提是得绕开几个默认配置陷阱——比如自动加载、Laravel 服务容器绑定、以及测试数据库隔离问题。
app() 返回 null 或报错?这是最常见的启动失败现象。Pest 默认不自动调用 Laravel 的测试启动逻辑(CreatesApplication trait),导致服务容器未初始化。
tests/Pest.php 中显式引入 Laravel 测试辅助函数:uses(Tests\TestCase::class)->in('Feature', 'Unit');Tests\TestCase 已继承 Illuminate\Foundation\Testing\TestCase,且含 use CreatesApplication;
require_once 'vendor/autoload.php' —— Pest 自带 autoloader,重复加载会破坏 Laravel 的容器单例database() → migrate() 在每个测试前重置干净?Pest 的 beforeEach 和 Laravel 的 RefreshDatabase trait 必须配合使用,否则迁移只跑一次或完全不跑。
uses(RefreshDatabase::class);
phpunit.xml 或 phpunit.xml.dist 中确认 DB_CONNECTION=sqlite 且 DB_DATABASE=:memory:
beforeEach 里手动 Artisan::call('migrate:fresh') —— 这会绕过 RefreshDatabase 的事务回滚机制,大幅拖慢速度factory()->create() 报 Class not found 怎么办?Laravel 9+ 已移除全局 factory() 辅助函数,Pest 里仍沿用旧写法容易出错。
User::factory()->create();
UserFactory 在 database/factories/UserFactory.php),且命名空间匹配User::factory() 返回的是 UserFactory 实例,不是静态代理 —— 不支持链式调用 create() 外的自定义方法,除非工厂里显式定义test('works') -> get('/api/users') -> assertStatus(200) 为什么返回 404?路由未加载,通常是因为 Pest 测试没走 Laravel 的 HTTP 内核,或中间件干扰了请求生命周期。
Illuminate\Foundation\Testing\RefreshDatabase 和 Illuminate\Foundation\Testing\WithFaker(后者非必须,但常配套)VerifyCsrfToken 中间件 —— 测试中默认关闭,但如果在 app/Http/Middleware/VerifyCsrfToken.php 里写了硬编码排除逻辑,可能意外拦截Route::get() 临时注册路由来“凑数”——Pest 的 HTTP 测试依赖真实路由缓存,应运行 php artisan con
fig:clear && php artisan route:clear 确保缓存更新最易被忽略的是 phpunit.xml 里的 bootstrap 路径是否指向 vendor/autoload.php 而非 Laravel 的 tests/bootstrap.php —— Pest 需要后者才能加载 Laravel 测试环境。这个配置错一位,整个测试就变成“裸 PHPUnit”,连 app() 都拿不到。
# php
# 数据库
# http
# 自动化
# Foundation
# 的是
# 加载
# 链式
# 这是
# 单元测试
# 几个
# 是因为
# 用了
# 写了
# database
# sqlite
# laravel
# bootstrap
# 编码
# app
# ai
# 路由
# 为什么
# 中间件
# NULL
# 命名空间
# xml
# 继承
# class
# 自定义