Laravel如何进行单元测试Pest_Laravel使用Pest测试框架编写自动化用例【指南】

14次阅读

Pest 测试需显式启用 Laravel 测试环境:在 tests/Pest.php 中调用 uses(TestsTestCase::class)->in(‘Feature’, ‘Unit’),并确保 TestCase 使用 CreatesApplication;数据库需配合 RefreshDatabase trait 与 :memory: SQLite;模型工厂改用 User::factory()->create();http 测试依赖正确 bootstrap 路径和路由缓存。

Laravel如何进行单元测试Pest_Laravel使用Pest测试框架编写自动化用例【指南】

直接用 Pestlaravel 单元测试,比原生 phpUnit 更轻、更直观,但前提是得绕开几个默认配置陷阱——比如自动加载、Laravel 服务容器绑定、以及测试数据库隔离问题。

为什么 Pest 测试里 app() 返回 NULL 或报错?

这是最常见的启动失败现象。Pest 默认不自动调用 Laravel 的测试启动逻辑(CreatesApplication trait),导致服务容器未初始化。

  • 必须在 tests/Pest.php 中显式引入 Laravel 测试辅助函数:
    uses(TestsTestCase::class)->in('Feature', 'Unit');
  • 确保 TestsTestCase继承 IlluminateFoundationTestingTestCase,且含 use CreatesApplication;
  • 不要手动调用 require_once 'vendor/autoload.php' —— Pest 自带 autoloader,重复加载会破坏 Laravel 的容器单例

如何让 database() → migrate() 在每个测试前重置干净?

Pest 的 beforeEach 和 Laravel 的 RefreshDatabase trait 必须配合使用,否则迁移只跑一次或完全不跑。

  • 在测试文件顶部启用 trait:
    uses(RefreshDatabase::class);
  • 若用内存 sqlite(推荐单元测试):在 phpunit.xmlphpunit.xml.dist 中确认 DB_CONNECTION=sqliteDB_DATABASE=:memory:
  • 避免在 beforeEach 里手动 Artisan::call('migrate:fresh') —— 这会绕过 RefreshDatabase 的事务回滚机制,大幅拖慢速度

测试 Eloquent 模型时,factory()->create()Class not found 怎么办?

Laravel 9+ 已移除全局 factory() 辅助函数,Pest 里仍沿用旧写法容易出错。

  • 改用类名调用工厂:
    User::factory()->create();
  • 确保模型已声明工厂路径(如 UserFactorydatabase/factories/UserFactory.php),且命名空间匹配
  • 如果用 PHP 8.1+,注意 User::factory() 返回的是 UserFactory 实例,不是静态代理 —— 不支持链式调用 create() 外的自定义方法,除非工厂里显式定义

test('works') -> get('/api/users') -> assertStatus(200) 为什么返回 404?

路由未加载,通常是因为 Pest 测试没走 Laravel 的 HTTP 内核,或中间件干扰了请求生命周期。

  • 确保测试类用了 IlluminateFoundationTestingRefreshDatabaseIlluminateFoundationTestingWithFaker(后者非必须,但常配套)
  • 检查是否启用了 VerifyCsrfToken 中间件 —— 测试中默认关闭,但如果在 app/Http/Middleware/VerifyCsrfToken.php 里写了硬编码排除逻辑,可能意外拦截
  • 别用 Route::get() 临时注册路由来“凑数”——Pest 的 HTTP 测试依赖真实路由缓存,应运行 php artisan config:clear && php artisan route:clear 确保缓存更新

最易被忽略的是 phpunit.xml 里的 bootstrap 路径是否指向 vendor/autoload.php 而非 Laravel 的 tests/bootstrap.php —— Pest 需要后者才能加载 Laravel 测试环境。这个配置错一位,整个测试就变成“裸 PHPUnit”,连 app() 都拿不到。

text=ZqhQzanResources