必须用 repositories.type = "path" 调试本地包,因其强制符号链接或目录映射,使 autoload-dev 生效;需确保 name、url、require-dev 三处严格一致,并运行 composer update 或 dump-autoload --dev 验证。

直接用 path 类型仓库,否则测试类根本加载不到、改了代码不生效、class_exists() 返回 false——这不是 PHPUnit 配置问题,是 Composer 根本没把你的本地包当“已安装包”对待。
为什么必须用 repositories.type = "path"
本地包调试唯一靠谱路径。其他方式全掉坑:
-
composer require vendor/pkg:dev-main但没配repositories→ 报Could not find package - 手动复制进
vendor/→autoload不认,composer dump-autoload无效,Windows 下静默 fallback 到 copy - 用 Git 仓库(
vcs)→ 每次改代码都得git commit && composer update,失去“边写边测”意义
path 类型强制符号链接(Linux/macOS)或目录映射(Windows),跳过版本解析,让 vendor/vendor/name 直接指向你本地源码目录,require-dev 和 autoload-dev 才能真实起作用。
composer.json 三处 name/url 必须严格对齐
错一个字符就失败,检查这三点:
- 本地包根目录的
composer.json中"name": "my-vendor/my-package"(注意大小写、连字符、斜杠) - 主项目
composer.json的repositories里"url": "./packages/my-package"(必须是相对于主项目composer.json的路径,不能含../) - 主项目
require-dev写"my-vendor/my-package": "@dev"(不是*,不是dev-main;@dev是唯一兼容所有分支别名的写法)
同时顶层加这两行,避免稳定性过滤:
"minimum-stability": "dev", "prefer-stable": true
测试类加载失败?先查 autoload-dev 和 dump-autoload
90% 的 Class not found 是 autoload 配置错,不是 PHPUnit 本身问题:
-
autoload-dev的 PSR-4 映射末尾必须带反斜杠:"MyPackage\Tests\": "tests/"(少\就断) - 如果测试文件在
tests/Unit/CalculatorTest.php,命名空间就得是MyPackageTestsUnit,不能漏层级 - 无命名空间的 bootstrap 文件(如
tests/bootstrap.php)不能塞进 PSR-4,要用autoload-dev.files单独列出来 - 改完
autoload-dev后,必须运行composer dump-autoload --dev,否则vendor/composer/autoload_dev.php不更新
验证是否真生效:
-
readlink vendor/my-vendor/my-package(Linux/macOS)看是不是软链 php -r "echo class_exists('MyPackage\Tests\CalculatorTest') ? 'ok' : 'fail';"
改了本地包代码,测试还是旧逻辑?别删 vendor/,要 update
path 类型仓库不是实时监听,但也不是完全静态:
- 改了
./packages/my-package里的源码,vendor/my-vendor/my-package内容不会自动变 - 正确做法是运行
composer update my-vendor/my-package(只刷新这个包,快且安全) - 千万别删
vendor/后composer install——这会让 Composer 把本地包当成普通 dist 包完整复制进去,彻底失去调试价值 - 如果只是改了测试类里的
use或命名空间,跑一次composer dump-autoload --dev就够
最易忽略的一点:Windows 用户看不到软链,得靠 dir vendormy-vendormy-package 确认它是不是个“目录重解析点”,否则你以为映射成功了,其实只是个空文件夹。


















