直接用 composer run 或 composer [script-name] 调用脚本,弃用 composer run-script;脚本名须严格匹配 composer.json 中 scripts 的键;Windows 下含冒号的脚本名需加双引号;传参必须用 -- 分隔;PHP 脚本需显式 require autoloader。

直接用 composer run 调用测试脚本就行,不用 composer run-script
Composer 从 2.0 开始已弃用 composer run-script,新项目一律用 composer run 或更短的 composer [script-name]。比如你定义了 "test": "phpunit",就直接运行 composer test,不加任何前缀或额外参数。
常见错误现象:运行 composer run-script test 会提示 Command "run-script" is deprecated;或者脚本名写成 phpunit(值)而非 test(键),结果报 Script not found。
- 脚本名必须严格匹配
composer.json中scripts下的键,大小写、短横线都不能错 - Windows 下含冒号的脚本名(如
test:unit)要加双引号:composer run "test:unit" - 运行
composer run --list是唯一可靠的方式,确认脚本是否被识别
phpunit 命令得能被系统找到,否则脚本会失败
很多项目把 phpunit 写在脚本里,但没指定路径,导致在 CI 或新环境里直接报 Command not found。根本原因是 phpunit 不在 $PATH 里,而 Composer 默认不加载 vendor/bin 到环境变量中。
- 推荐写成
"test": "vendor/bin/phpunit",绝对路径最稳 - 如果用了自定义配置文件,记得带上
-c phpunit.xml.dist - 想只跑某个测试类?用
"test:calc": "vendor/bin/phpunit tests/CalculatorTest.php" - 避免用
phpunit全局命令——它版本不可控,CI 环境常缺失
传参必须用 -- 显式分隔,不然会被 Composer 吞掉
比如你想过滤某个测试方法:composer test --filter=testAdd 看似合理,实际会失败——--filter 被 Composer 当作自身选项处理,不是传给 phpunit 的。
- 正确写法是:
composer test -- --filter=testAdd,中间的--是 shell 约定,表示“后面参数全透传” - 多个参数也一样:
composer test -- --filter=testAdd --verbose --colors=always - 如果脚本值是数组(如
["vendor/bin/phpunit", "--filter=testAdd"]),参数会原样透传,无需额外-- - PHP 脚本里别依赖
$_SERVER['argv']解析,改用getenv('COMPOSER_ARGS')(Composer 4.0+)更可靠
脚本里要手动加载 autoloader,否则 Class not found
Composer 执行脚本时不会自动 require vendor/autoload.php,所以哪怕你写了 "test": "php tests/ExampleTest.php",里面 new 一个项目类也会直接报错。
- 所有内联 PHP 脚本开头必须加:
require __DIR__ . '/vendor/autoload.php'; - 推荐把逻辑抽到独立文件(如
scripts/run-test.php),再在scripts里写"test": "php scripts/run-test.php" - 不要假设当前目录一定是项目根目录——
__DIR__指向的是composer.json所在位置,相对路径以此为准 - 如果用了
autoload-dev,确保测试类路径已注册,否则composer dump-autoload后再试
真实可用的最小闭环就这四步:定义脚本键名 → 用绝对路径调用 vendor/bin/phpunit → 传参加 -- 分隔 → PHP 脚本里显式 require autoloader。漏掉任意一环,都可能在本地跑通、CI 上失败。











