核心卡点是依赖位置、自动加载和配置识别:phpunit版本须手动锁死(php 7.4/8.0用^9.6,8.1用^10.5,8.2+试^11.0);需配置autoload-dev并执行dump-autoload;phpunit.xml.dist须置于根目录且含bootstrap="vendor/autoload.php";必须用./vendor/bin/phpunit运行。

composer 配合 phpunit 不是“装完就能跑”,核心卡点就三个:依赖装在哪儿、类能不能自动加载、配置文件认不认你。其他都是这三个问题的变形。
composer require --dev phpunit/phpunit 版本必须手动锁死
不指定版本,composer require --dev phpunit/phpunit 可能拉到 ^11.0,但你的 PHP 是 8.1 就直接报 Declaration of PHPUnitFrameworkTestCase::setUp(): void must be compatible——这不是你代码错,是语法层不兼容。
- PHP 7.4 或 8.0 → 用
composer require --dev phpunit/phpunit:^9.6 - PHP 8.1 → 用
composer require --dev phpunit/phpunit:^10.5 - PHP 8.2+ → 可试
^11.0,但确认项目没调用已移除的phpunit-skelgen
装完立刻验证:./vendor/bin/phpunit --version,输出版本号且无 fatal error 才算过关。
autoload-dev 和 composer dump-autoload 缺一不可
即使 phpunit 装对了,Class 'TestsUnitExampleTest' not found 还是会报——因为 tests/ 目录根本没注册进 autoloader。
- 确保
composer.json里有"autoload-dev"段,且映射正确,例如:"Tests\": "tests/" - 改完
composer.json后,必须执行composer dump-autoload(不是dump-autoload --no-dev) - CI 环境里加一句验证:
composer dump-autoload --no-dev && php -r "echo class_exists('Tests\Unit\ExampleTest') ? 'ok' : 'fail';"
漏掉 dump-autoload,所有后续错误都只是表象;它不运行,phpunit 就永远找不到你的测试类。
phpunit.xml.dist 必须放在根目录,且 bootstrap 不能少
./vendor/bin/phpunit 默认只读当前目录下的 phpunit.xml 或 phpunit.xml.dist。名字差一个字符、放错位置、或者被 IDE 缓存,就会静默回退到默认扫描逻辑,结果常是 No tests executed。
- 文件必须和
composer.json同级,命名推荐phpunit.xml.dist(某些 CI 工具默认找这个) -
bootstrap="vendor/autoload.php"是刚需,缺了这句,use AppHttpController就会Class not found -
<directory>tests</directory>写相对路径,别写./tests或绝对路径——CI 里路径一变全废
最简可用配置就三行有效内容,其余可删:
<?xml version="1.0" encoding="UTF-8"?><phpunit bootstrap="vendor/autoload.php"><testsuites><testsuite name="default"><directory>tests</directory></testsuite></testsuites></phpunit>
永远用 ./vendor/bin/phpunit,别信全局 phpunit 命令
phpunit 命令在终端里报 command not found 是正常现象。Composer 不往系统 PATH 里塞东西,它只把二进制放 vendor/bin/ 下。
- Linux/macOS:必须用
./vendor/bin/phpunit - Windows:用
vendorinphpunit(CMD)或vendor/bin/phpunit(Git Bash) - 想图方便?在
composer.json的scripts里加"test": "phpunit",然后跑composer test—— 这个phpunit是 Composer 自动解析到vendor/bin的,安全
用全局 phpunit,phpunit.xml.dist 不生效、autoload.php 加载错、覆盖率统计为空……这些问题全是因为入口错了。真正难调的,往往就是少敲了那两个点和斜杠。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











