composer插件测试必须在真实composer进程中运行,通过path仓库加载未发布插件并触发命令或事件,检查输出、文件生成、退出码等副作用;事件监听须在activate()中注册,自定义命令需用子进程捕获真实cli行为。

Composer插件测试必须在真实 Composer 进程中跑
本地 phpunit 直接 new 插件类跑测试,90% 的情况会失败——因为 Composer 插件的生命周期、事件绑定、IOInterface、ComposerAutoloadAutoloadGenerator 等都依赖完整 Composer 运行时上下文。不模拟真实调用链,测了也白测。
正确做法是让 Composer 自己加载你的插件,再触发对应命令或事件:
- 把插件以
path方式 require 进一个临时测试项目(不是插件源码根目录) - 用
composer install --no-cache触发插件激活 - 执行具体命令如
composer dump-autoload或自定义命令,观察输出/副作用 - 检查生成文件、日志、退出码、临时目录状态等作为断言依据
怎么让 Composer 在测试中加载未发布插件
别改 composer.json 的 repositories 去配 vcs,太重;也别提前 composer global require,污染环境。最干净的方式是用 path 仓库 + 本地绝对路径:
{
"repositories": [
{
"type": "path",
"url": "/absolute/path/to/your/plugin"
}
],
"require": {
"your-vendor/your-plugin": "*"
}
}
注意两点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
url必须是绝对路径,相对路径在 CI 中极易出错 - 插件包的
composer.json里必须声明"type": "composer-plugin"和"extra": {"class": "Your\Plugin\Class"} - 如果插件用了
composer-plugin-api版本约束,测试项目的 Composer 版本必须匹配(比如^2.2插件不能在 Composer 1.x 下测)
监听事件时为什么 test 里收不到 event
常见现象:写了 activate(),注册了 Event::PRE_AUTOLOAD_DUMP,但跑测试时回调压根没触发。根本原因是事件监听器注册时机不对——必须在插件 activate() 执行期间注册,且 EventDispatcher 实例来自 Composer 主进程,不是你 new 出来的 mock。
实操要点:
- 不要在构造函数里注册事件,
activate()是唯一可靠入口 - 确保监听的事件名拼写完全一致:
ScriptEvents::POST_INSTALL_CMD≠ScriptEvents::POST_UPDATE_CMD - 调试时可在监听器里加
file_put_contents('/tmp/event.log', print_r($event, true), FILE_APPEND),确认是否进入 - 某些事件(如
PackageEvents::POST_PACKAGE_INSTALL)只在实际安装包时触发,composer install无新包则不会触发
测试自定义命令时如何捕获输出和返回值
Composer 自定义命令继承 Command,但它的 execute() 不直接 return,而是靠 $input/$output 和退出码通信。测试时不能只看 return,得模拟真实 CLI 调用流:
- 用
proc_open()或shell_exec()启动子进程执行composer your:command --no-ansi - 捕获 stdout/stderr 并断言关键词,例如检查是否输出
"Generated config at vendor/xxx/config.php" - 检查退出码:
0表示成功,非0才是错误(很多插件误把 warning 当 error) - 避免用
setOutput()mock 输出对象——它不触发 Formatter、颜色控制、进度条等真实行为
真正难的不是写断言,而是还原那个“插件被 Composer 加载 → 用户敲命令 → Composer 解析并调用 → 插件响应”的链路。漏掉任意一环,测试就只是个玩具。










