Coolify 中的 Pest 4 测试实战:从 make:test 到浏览器测试与架构测试

Coolify 中的 Pest 4 测试实战:从 make:test 到浏览器测试与架构测试 Coolify 中的 Pest 4 测试实战从 make:test 到浏览器测试与架构测试【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolifyCoolify 的整个后端测试体系tests/目录下约 900 个测试文件统一采用 Pest 4 编写。本篇基于仓库中的.agents/skills/pest-testing/SKILL.md技能文档结合phpunit.xml、tests/Pest.php与真实测试文件讲清在 Coolify 这类 Laravel 项目中如何创建、组织、运行 Pest 测试以及 Pest 4 新增的浏览器测试、冒烟测试、视觉回归、分片与架构测试的实际落地方式。读完本文你能够按项目规范新增 Feature/Unit/Browser 测试正确使用 datasets、mock 与RefreshDatabase并理解 Coolify 测试环境的隔离机制。测试工具链与版本基线从composer.json可以看到 Coolify 的测试相关依赖pestphp/pest: ^4.7.8—— 核心测试框架pestphp/pest-plugin-browser: ^4.3.1—— Pest 4 的浏览器测试插件visit()等 API 的来源laravel/dusk: ^8.6.0—— 传统 Dusk 浏览器测试tests/Browser/LoginTest.php仍在使用laravel/framework: ^12.65.0配合pestphp/pest-plugincomposer.json 的 autoload-dev 中注册使uses()、mock()等 Laravel 集成开箱即用。两条规则先立起来所有测试必须用 Pest 编写未经批准不得删除已有测试——它们属于核心应用代码的一部分。创建测试make:test 的正确用法生成新测试统一使用 Artisan 命令{name}参数只包含路径和测试名不能包含测试套件名错误php artisan make:test --pest Feature/SomeFeatureTest会生成tests/Feature/Feature/SomeFeatureTest.php目录重复正确php artisan make:test --pest SomeControllerTest生成tests/Feature/SomeControllerTest.php错误php artisan make:test --pest --unit Unit/SomeServiceTest会生成tests/Unit/Unit/SomeServiceTest.php正确php artisan make:test --pest --unit SomeServiceTest生成tests/Unit/SomeServiceTest.php。目录组织规范测试类型目录说明Unit / Featuretests/Unit/、tests/Feature/单元测试与 HTTP/业务集成测试浏览器测试tests/Browser/真实浏览器集成测试历史版本回归tests/v4/旧版本行为对照测试含v4/BrowserTestCase 绑定tests/Pest.phptests/Pest.php 通过uses()将 Laravel 测试基类绑定到对应目录这决定了哪些目录的测试闭包能调用$this-get()、$this-actingAs()等实例方法uses(TestCase::class)-in(Feature, v4/Feature, v4/Browser, v5/Browser);同一文件中还定义了全局beforeEach钩子用于保证测试间状态隔离——这是 Coolify 特有的必要清理beforeEach(function () { // Flush the Once memoization cache to ensure tests get fresh data Once::flush(); // Flush the Server identity map cache to ensure tests get fresh data Server::flushIdentityMap(); // 宿主机 Pest 运行无法解析 docker DNScoolify-realtime关闭广播 config([broadcasting.default null]); });基本测试结构test() 与 it()Pest 同时支持test()与it()两种写法。写新测试前先查看同目录现有测试遵循哪种惯例已有测试用test()就沿用test()用it()就沿用it()。最简结构it(is true, function () { expect(true)-toBeTrue(); });Coolify 仓库的真实用例tests/Feature/AllResourceRestartLimitsTest.php展示了标准的 Pest 风格——闭包接收参数、expect()链式断言、uses(RefreshDatabase::class)声明数据库刷新use Illuminate\Foundation\Testing\RefreshDatabase; uses(RefreshDatabase::class); it(gives every independently runnable non-application resource restart limit state, function (string $modelClass) { expect(class_uses_recursive($modelClass))-toContain(HasRestartLimit::class); $resource new $modelClass; expect($resource-getFillable())-toContain( restart_count, max_restart_count, restart_limit_reached, last_restart_at, last_restart_type, )-and($resource-getCasts())-toMatchArray([ restart_count integer, max_restart_count integer, restart_limit_reached boolean, last_restart_at datetime, ]); });需要说明的取值惯例数据库访问类测试普遍以文件头use Illuminate\Foundation\Testing\RefreshDatabase;uses(RefreshDatabase::class);的方式为每个测试提供干净的数据库状态仓库中tests/Feature/下大量 API 测试均如此部分需要预置大量数据的浏览器测试则改用手动 seed 辅助函数见下文seedBrowserResourceStack。运行测试定稿前先用过滤器跑最小集php artisan test --compact --filtertestName跑全部测试php artisan test --compact跑单个文件php artisan test --compact tests/Feature/ExampleTest.php。测试环境由 phpunit.xml 统一配置其中关键环境变量值得注意环境变量值作用APP_ENVtesting测试环境标识DB_CONNECTIONtesting使用专用测试数据库连接CACHE_DRIVER/SESSION_DRIVERarray进程内缓存与会话测试间零残留QUEUE_CONNECTIONsync队列同步执行避免依赖 HorizonMAIL_MAILERarray邮件不真正发送BCRYPT_ROUNDS4降低密码哈希成本加快测试BROADCAST_DRIVERnull宿主机浏览器测试无法解析 docker DNS 中的实时推送服务强制关闭phpunit.xml定义了Unit、Feature、v4三个测试套件均以Test.php为后缀而 Dusk 浏览器套件由独立的 phpunit.dusk.xml 定义指向tests/Browser目录——也就是说传统 Dusk 测试需要显式指定该配置文件运行。断言用具体断言替代 assertStatusHTTP 测试应使用语义化断言而不是裸状态码使用替代assertSuccessful()assertStatus(200)assertNotFound()assertStatus(404)assertForbidden()assertStatus(403)it(returns all, function () { $this-postJson(/api/docs, [])-assertSuccessful(); });Coolify 的 API 测试如tests/Feature/Api/下各文件大量采用actingAs()getJson()/postJson() 链式响应断言的组合配合工厂创建的资源进行前置数据构造。Mocking使用mock()前必须导入该函数use function Pest\Laravel\mock;值得注意的是Coolify 仓库的存量测试中更常见的是直接使用 Mockery 的接口如 tests/Feature/Api/CloudProviderTokenApiTest.php 中的Log::shouldReceive(channel)-with(audit)-andReturn($auditChannel);而Pest\Laravel\mock()是其语法糖封装。两者可以混用新增代码遵循技能文档要求使用use function Pest\Laravel\mock;即可。Datasets消除重复测试对于验证规则、多模型覆盖这类重复场景用-with()传入数据集it(has emails, function (string $email) { expect($email)-not-toBeEmpty(); })-with([ james jameslaravel.com, taylor taylorlaravel.com, ]);上文AllResourceRestartLimitsTest.php就是典型的 dataset 用法——一个测试闭包配合-with([...])遍历ApplicationPreview、StandaloneClickhouse、StandaloneKeydb等十余个资源模型类把每个可独立运行的资源都具备重启限制字段这一约定压缩成一处断言新增模型时只需往数据集里加一行。Pest 4 新特性总览特性用途Browser Testing真实浏览器中的完整集成测试Smoke Testing快速验证多个页面无 JS 报错Visual Regression截图比对检测视觉变化Test Sharding测试分片并行 CI 运行Architecture Testing强制代码规范浏览器测试浏览器测试运行在真实浏览器中用于完整集成测试。规则要点存放在tests/Browser/目录Pest 的visit()风格浏览器测试按tests/Pest.php的uses()绑定还分布于v4/Browser、v5/Browser可正常使用 Laravel 特性Event::fake()、assertAuthenticated()、模型工厂等用RefreshDatabase保证每个测试的干净状态页面交互覆盖点击、输入、滚动、选择、提交、拖放、触控手势按需测试多浏览器Chrome、Firefox、Safari、多设备视口iPhone 14 Pro、平板、切换明暗配色调试时可截图或暂停测试。标准示例密码重置流程it(may reset the password, function () { Notification::fake(); $this-actingAs(User::factory()-create()); $page visit(/sign-in); $page-assertSee(Sign In) -assertNoJavaScriptErrors() -click(Forgot Password?) -fill(email, nunolaravel.com) -click(Send Reset Link) -assertSee(We have emailed your password reset link!); Notification::assertSent(ResetPassword::class); });assertNoJavaScriptErrors()是浏览器测试的必选项——它是发现前端 JS 报错的主要手段。Coolify 把浏览器测试的通用动作沉淀在两个层面tests/Pest.php 中的loginAndSkipBoarding()全局辅助函数自动完成/login页面的账号密码填写、点击登录并执行一段内联 JS 点击首次登录时的 skip setup 按钮以跳过引导页最后wait(1.5)等待页面稳定tests/Support/BrowserTestHelpers.php 由tests/Pest.php通过require_once加载提供seedBrowserResourceStack()一次性构造 InstanceSettings、root 用户、SSH 私钥、服务器、StandaloneDocker 部署目标、项目与环境的完整 fixture、selectListboxOption()操作 Alpine.js listbox 下拉选项、submitLivewireForm()提交 Livewire 表单等辅助函数——这些函数正是文档中点击、选择、提交等交互能力在真实项目里的封装形态。另外要区分仓库中tests/Browser/LoginTest.php属于传统Laravel Dusk风格namespace Tests\Browser、继承Tests\DuskTestCase、$this-browse(function (Browser $browser) {...})它由 phpunit.dusk.xml 套件驱动与 Pest 的visit()浏览器测试是两套并存机制。冒烟测试一次性访问多个页面快速验证无 JavaScript 错误$pages visit([/, /about, /contact]); $pages-assertNoJavaScriptErrors()-assertNoConsoleLogs();这是上线前低成本的前端回归手段批量页面 无 JS 报错 无异常控制台日志三重校验。视觉回归测试通过截图捕获与比对来检测视觉变化适用于 UI 重构或模板改动后快速发现布局回归。测试分片将测试集拆分到多个并行进程执行用于加速 CI 流水线。架构测试Pest 4 继承了架构测试能力可用于强制代码规范arch(controllers) -expect(App\Http\Controllers) -toExtendNothing() -toHaveSuffix(Controller);对 Coolify 这类app/Http/Controllers/下有 48 个控制器文件的项目toHaveSuffix(Controller)、命名空间约束这类架构断言可以持续守护目录约定不被破坏。常见陷阱清单使用mock()前忘记导入use function Pest\Laravel\mock;用assertStatus(200)而非assertSuccessful()重复的验证规则测试忘记使用 datasets未经批准删除已有测试浏览器测试中忘记assertNoJavaScriptErrors()make:test的{name}参数里重复了Feature/或Unit/前缀延伸阅读路径测试总入口与环境绑定tests/Pest.php、tests/TestCase.php运行配置phpunit.xml、phpunit.dusk.xmldataset RefreshDatabase 范例tests/Feature/AllResourceRestartLimitsTest.php浏览器测试共享辅助tests/Support/BrowserTestHelpers.phpDusk 风格示例tests/Browser/LoginTest.phpAPI 集成测试示例tests/Feature/Api/CloudProviderTokenApiTest.php【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考