不能。run-script仅顺序执行命令,不感知退出码;需用shell脚本封装phpunit并用||判断失败后执行git stash pop回滚,再通过"test:rollback": "bash test-with-rollback.sh"调用。

run-script 能不能直接触发测试失败后的回滚?
不能。Composer 的 run-script 本身不感知脚本执行结果,更不会自动根据 PHPUnit 退出码做分支处理——它只负责按顺序调用命令,哪怕 phpunit 返回非零状态码,后续命令默认仍会继续执行。
如何让 PHPUnit 失败时跳过后续操作并触发回滚?
必须靠 shell 控制流显式判断 PHPUnit 的退出码。常见做法是把测试和回滚逻辑封装进一个可执行脚本(如 test-with-rollback.sh),再在 composer.json 中通过 run-script 调用它:
#!/bin/bash
vendor/bin/phpunit "$@" || { echo "PHPUnit failed, rolling back..."; git stash pop 2>/dev/null || true; exit 1; }
关键点:
-
||是 Bash 短路运算符,仅当前面命令退出码非 0 时才执行右边 -
git stash pop假设你已在测试前用git stash push保存了工作区变更 -
2>/dev/null || true防止 stash 不存在时脚本报错中断 - 最后的
exit 1确保整个脚本失败,让 CI 或 Composer 流程感知到异常
在 composer.json 中怎么安全定义这个 script?
避免在 scripts 字段里写多行复杂逻辑(JSON 不支持换行、引号易出错),推荐指向外部脚本:
"scripts": {
"test:rollback": "bash test-with-rollback.sh"
}
这样做的好处:
- 逻辑可调试、可加日志、可复用
- 不用在 JSON 里逃逸双引号或分号
- CI 环境中更容易单独运行验证
- 如果用
phpunit --fail-on-warning或自定义--stop-on-failure,也一并生效
为什么不能只依赖 PHPUnit 的 --stop-on-failure?
--stop-on-failure 只控制测试套件内部是否提前终止,不影响 run-script 后续命令执行。它和“回滚”完全无关——回滚动作必须由外部流程控制,且需明确区分“测试未运行”“测试运行但失败”“测试运行成功但后续命令出错”三种状态。最容易被忽略的是:没有预存变更快照(比如没 git stash push)就执行 git stash pop,会导致静默失败或覆盖当前修改。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











