答案是laravel版本低于9.27或pest包未正确安装,需先确认php artisan --version≥9.27,再执行composer require --dev pestphp/pest pestphp/pest-plugin-laravel并运行php artisan pest:install,同时清空bootstrap/cache/config.php避免缓存干扰。

php artisan pest:install 报 Command not found 怎么办
说明 Laravel 版本低于 9.27,或 Pest 包未正确安装。Pest 的 Laravel 集成命令依赖底层支持,不是“装了就能用”。
- 先运行
php artisan --version确认版本 ≥ 9.27;低于该版本需升级 Laravel 或手动配置 - 执行
composer require --dev pestphp/pest pestphp/pest-plugin-laravel,不要跳过pest-plugin-laravel - 安装后若仍报错,清空
bootstrap/cache/config.php并重试,避免配置缓存干扰命令注册 - 别手动改
composer.json后直接composer install—— 必须让 Laravel 的服务提供者自动注册命令
test() 和 it() 在 Pest 里到底怎么选
语义上没强制区别,但行为一致性取决于你是否显式启用 Laravel 插件和上下文绑定。
-
it()更适合单断言、行为描述型用例,比如it('redirects when not authenticated', ...) -
test()更适合多步骤逻辑,比如创建资源 → 修改状态 → 验证权限链路 - 两者闭包内都能直接调用
get()、postJson()、$this->actingAs(),前提是tests/Pest.php中已声明uses(Tests\TestCase::class)->in('Feature', 'Unit') - 如果闭包里用了
expect()却报Call to undefined function expect(),说明没启用pest-plugin-assertions:运行composer require --dev pestphp/pest-plugin-assertions并在Pest.php中调用uses(Expectations::class)
数据库迁移不生效或变慢的三个关键点
不是写个 RefreshDatabase trait 就万事大吉 —— Pest 的生命周期和 Laravel 测试辅助机制必须对齐。
- 必须在测试文件顶部(非闭包内)调用
uses(RefreshDatabase::class),不能只靠beforeEach里手动Artisan::call('migrate:fresh'),后者会绕过事务回滚,导致每个测试都重建全库 - 确保
.env.testing或phpunit.xml中DB_CONNECTION=sqlite且DB_DATABASE=:memory:,否则RefreshDatabase无法高效回滚 - 模型工厂别再用全局
factory()->create()—— Laravel 9+ 已移除,改用User::factory()->create(),且确认UserFactory类存在、命名空间匹配、路径为database/factories/UserFactory.php
为什么 $this->get() 报 Call to undefined method 或 app() 返回 null
这是 Pest 没加载 Laravel 测试上下文的典型症状,不是代码写错了,而是入口配置漏了。
-
tests/Pest.php必须包含uses(Tests\TestCase::class)->in('Feature', 'Unit'),缺一不可 -
Tests\TestCase必须继承Illuminate\Foundation\Testing\TestCase,且含use CreatesApplication; - 绝对不要在测试文件里写
require_once 'vendor/autoload.php'—— Pest 自带 autoloader,重复加载会破坏容器单例,导致app()失效 - 如果用 PHP 8.1+,
User::factory()返回的是工厂实例,不是静态代理,所以User::factory()->for($team)->create()可行,但User::factory()->customMethod()->create()会失败,除非你在工厂类里明确定义了customMethod()
uses() 调用,就可能让整个测试跑在裸 PHPUnit 环境里。











