Composer不参与负载调度,仅负责依赖安装;测试负载问题需通过--no-dev控制安装、scripts实现按需执行、PHP扩展配置优化等手段解决,而非依赖Composer调度。

Composer 本身不参与“负载调度”——它只管装包,不管运行时资源分配或任务分发。所谓“测试环境依赖的负载调度”,其实是误用术语。真实需求通常是:在 CI/CD、本地测试或并行执行多个测试套件时,避免因 require-dev 中的工具(如 phpunit、phpstan、prophecy)引发资源争抢、内存溢出或启动延迟。解决方向不是让 Composer 调度,而是控制安装、加载和执行粒度。
为什么 composer install --no-dev 不能解决测试负载问题
很多人以为加了 --no-dev 就能“轻量运行测试”,但这是错觉:
– 它只跳过安装 require-dev 的包,不影响测试代码本身对这些工具的调用
– 如果你的测试启动脚本(如 phpunit.xml 或 phpstan.neon)仍被加载,进程照样会 fork、占用 CPU 和内存
– 更隐蔽的是:某些 autoload-dev 规则(如 PSR-4 映射 "Tests\": "tests/")仍生效,导致测试类被提前加载进内存,哪怕你没跑测试
真正影响测试负载的三个关键点
-
phpunit默认单进程串行执行,但可通过--process-isolation或paratest启用多进程 —— 这才是负载调度的起点,不是 Composer 的事 -
phpstan和psalm支持--configuration指定分析范围,跳过 vendor 或生成代码目录,直接减少扫描耗时与内存占用 - CI 环境中,
composer install和vendor/bin/phpunit常被塞进同一个 job,导致冷启动慢;应拆成独立步骤,并用--no-interaction --no-progress --optimize-autoloader加速安装阶段
如何让测试依赖“按需加载”,而非全量驻留
核心思路是:把高开销工具从 require-dev 移到 scripts + 独立 bin wrapper,实现懒加载:
{
"scripts": {
"test:unit": "phpunit --configuration phpunit.unit.xml",
"test:integration": "phpunit --configuration phpunit.int.xml --process-isolation",
"analyze:static": "phpstan analyse --configuration=phpstan.neon src/",
"lint:php": "php -l $(find src/ -name "*.php")"
},
"require-dev": {
"phpunit/phpunit": "^9.6",
"phpstan/phpstan": "^1.10",
"phpspec/prophecy": "^1.19"
}
}
这样做的实际效果:
- CI 脚本里只跑
composer run test:unit,其他工具不会被 autoload 或初始化 - 本地开发时,可单独
composer require --dev friendsofphp/php-cs-fixer并加到 scripts,不影响测试流程 - 若某次构建只需 lint,就只执行
composer run lint:php,phpunit和phpstan的 autoloader 根本不触发
最常被忽略的一点:PHP 扩展本身(如 opcache、pcov)的配置比 Composer 依赖更能决定测试负载。比如 pcov 在覆盖率收集时内存翻倍,但它和 require-dev 无关——得靠 php.ini 控制启用时机,而不是靠 Composer 调度。


















