mcpField
S
speeding-up-laravel-tests

speeding-up-laravel-tests

github.com/freekmurze测试与质量1.0k38 次安装1 周前更新
代码仓库

关于 speeding-up-laravel-tests

面向 Laravel 开发者的测试提速清单,涵盖环境配置、外部交互模拟、数据库开销和性能分析,并优先列出低成本的环境调整。

主要功能

  1. 01调整测试环境配置
  2. 02模拟外部交互
  3. 03降低数据库准备开销
  4. 04分析慢速测试

适用场景

  1. 01缩短耗时较长的 CI 测试
  2. 02排查单个慢速测试
  3. 03为新项目建立测试检查清单

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/freekmurze/dotfiles --skill speeding-up-laravel-tests

安装后在 Claude Code 中输入/speeding-up-laravel-tests确认已加载。

详细介绍

加快 Laravel 测试

精选的 Laravel 测试套件提速技巧。建议大致按以下顺序应用;修复环境通常能以最少的工作带来最大的收益。

适用场景

  • 测试套件平均每个测试耗时超过几秒。
  • CI 耗时不断增加,你希望缩短几分钟。
  • 某个特定测试运行缓慢,你想检查它实际在做什么。
  • 你正在接手一个新项目,想要一份标准检查清单。

环境和配置

  • 在 .env.testing(或 phpunit.xml)中设置 BCRYPT_ROUNDS=4。 默认值为 12,而哈希计算会显著拖慢身份验证测试。
  • 禁用 XDebug。 大规模测试时也禁用 pcov,除非你确实需要覆盖率。
  • 在测试环境中禁用后台运行的包: Pulse、Telescope、Nightwatch 及其他类似的第三方包,这些包会在每次请求或命令中执行工作。
  • 使用 WithCachedConfig 和 WithCachedRoutes trait,避免每次测试都重新解析配置和路由。
  • 在测试设置中调用 withoutVite()(或 withoutMix()), 避免框架尝试解析已构建的资源。

模拟外部交互

任何与非测试目标外部服务的交互都应进行模拟。

  • Notification::fake()、Mail::fake()、Bus::fake()、Event::fake()、Queue::fake()。
  • 会分发任务的 HTTP 端点: 除非测试要断言任务行为,否则应模拟队列。否则任务会以内联方式执行,并引入它们涉及的所有内容。
  • 事件监听器: 如果不相关的监听器被触发并执行工作,就对它们使用 Event::fake()。利用 Laravel 的事件系统,查明慢速测试期间触发了哪些事件。
  • 在测试套件中使用 Http::preventingStrayRequests()。 一个缓慢的意外请求就可能拖慢每个测试。请注意,这只能捕获通过 Laravel HTTP 客户端发出的请求。请另行检查直接使用 Guzzle / cURL 的情况。
  • 使用 Sleep::fake(syncWithCarbon: true), 避免重试和退避逻辑真的休眠。要求代码使用 Sleep 助手,而不是 PHP 的 sleep()。
  • 使用 Exceptions::fake(), 确保测试中不会向 Flare/Sentry/Bugsnag 报告异常。

数据库

  • 用 LazilyRefreshDatabase 替代 RefreshDatabase。 从未访问数据库的测试可以完全跳过迁移和截断的开销。
  • 检查工厂的使用情况。 工厂是常见的性能热点,因为很容易创建出超出测试所需的模型。留意嵌套的 create() 调用是否生成了额外记录。
  • 使用 $factory->recycle($model) 创建一个共享的父模型,并将其传递给嵌套的工厂调用,而不是让每个嵌套工厂都创建自己的父模型。

性能分析与诊断

  • ./vendor/bin/pest --profile 会列出每个分片中最慢的测试。从这里开始排查。耗时最长的 10 个测试中发现的模式往往也适用于整个测试套件。
  • 使用 https://marmelab.com/phpunit-d3-report/ 可视化测试套件(最初面向 PHPUnit;请确认与 Pest 兼容)。
  • 如果某个测试为何缓慢难以查明,可以检测事件监听器或添加临时日志,找出幕后发生的意外工作。

快速参考

区域操作
哈希计算BCRYPT_ROUNDS=4
调试器禁用 XDebug,禁用 pcov
后台包禁用 Pulse、Telescope、Nightwatch
配置 / 路由WithCachedConfig、WithCachedRoutes
资源withoutVite() / withoutMix()
外部服务Notification::fake()、Mail::fake()、Bus::fake()、Event::fake()、Queue::fake()
HTTPHttp::preventingStrayRequests()
休眠Sleep::fake(syncWithCarbon: true)
异常Exceptions::fake()
数据库LazilyRefreshDatabase
工厂$factory->recycle($model),检查嵌套的创建操作
性能分析pest --profile

常见错误

  • 即使测试不会访问数据库,也在每个测试中启用 RefreshDatabase。
  • 在生产代码中调用真实的 sleep() 或使用 Carbon,导致 Sleep::fake() 无法发挥作用。
  • 添加 Queue::fake(),却仍然断言作业的副作用(这些副作用永远不会发生)。
  • 为了以防测试失败,运行测试套件时加载 XDebug。
  • 因为从未创建 .env.testing,而让 BCRYPT_ROUNDS 保持默认值。

评论

支持 Markdown