PHPUnit 不绑定 PHP 版本,但必须用对应 PHP 版本的 composer 安装并执行 ./vendor/bin/phpunit;全局安装易冲突,应显式指定 PHP 解释器路径,严格匹配版本约束与 autoload 配置。

直接说结论:PHPUnit 本身不绑定 PHP 版本,但你必须用对应 PHP 版本的 composer 安装它,并确保 vendor/bin/phpunit 被该 PHP 版本执行——否则 Class 'PHPUnit\Framework\TestCase' not found 或 ParseError: syntax error 这类报错几乎必然出现。
phpunit 命令找不到?别碰全局安装
很多人在多版本 PHP 环境下第一反应是“把 phpunit 加进 PATH”,结果发现 phpunit --version 输出的版本和当前项目 PHP 版本对不上,或者干脆报错找不到命令。这不是 PATH 配得不对,而是误信了“全局安装更方便”的旧思路。
- 新版 Composer 默认不把
phpunit放进全局 bin,硬加--global容易和项目 PHP 版本冲突 - 不同 PHP 版本(比如 PHP 7.4 和 PHP 8.2)可能依赖不同 major 版本的 PHPUnit(如 ^9.6 vs ^10.5),全局只有一个二进制根本无法兼容
- 正确做法:始终用
./vendor/bin/phpunit,并显式指定 PHP 解释器,例如:/usr/local/bin/php82 ./vendor/bin/phpunit - 如果你用
brew install php@8.2,它的可执行路径通常是/opt/homebrew/bin/php@8.2(macOS)或/usr/local/bin/php82(Linux),别直接写php
composer require --dev phpunit/phpunit 装错了版本?看 PHP 主版本号
Composer 安装时如果不指定版本约束,可能拉到一个和当前 PHP 不兼容的 PHPUnit,比如在 PHP 7.4 下装了 PHPUnit 10.x(要求 PHP 8.1+),就会在运行时直接 parse 失败。
- PHP 7.4 → 用
phpunit/phpunit:^9.6(最高支持 PHP 7.4) - PHP 8.0–8.1 → 可选
^9.6或^10.1(确认composer.json中"platform": {"php": "8.1"}已设) - PHP 8.2+ → 推荐
phpunit/phpunit:^10.5(2026 年主流稳定版) - 执行前先确认当前 CLI 的 PHP 版本:
php -v,再用对应版本的php执行 composer:/path/to/php82 /path/to/composer.phar require --dev phpunit/phpunit:^10.5 - 装完检查
vendor/phpunit/phpunit/ChangeLog.md里第一条是否匹配你的 PHP 版本要求
tests/CalculatorTest.php 运行时报 Class 'PHPUnit\Framework\TestCase' not found
这不是 PHPUnit 没装,是自动加载没触发。TestCase 类根本没被引入,use 语句再对也没用。
立即学习“PHP免费学习笔记(深入)”;
- 测试文件顶部必须有
require_once 'vendor/autoload.php';—— 即使你用了 PSR-4,也得显式加载一次启动入口 - 确认
composer.json里有"autoload-dev"区块,哪怕只是空的{},否则vendor/autoload.php不会加载测试命名空间 -
phpunit.xml里必须写明bootstrap="vendor/autoload.php",或者命令行加--bootstrap vendor/autoload.php - 类名和文件名要严格匹配:
CalculatorTest必须放在tests/CalculatorTest.php,大小写都不能错(Windows 下容易忽略这点) - 如果用
./vendor/bin/phpunit tests/CalculatorTest.php运行单个文件,它绕过phpunit.xml配置,autoload和bootstrap很可能失效;应改用./vendor/bin/phpunit --filter CalculatorTest
断言通过但逻辑没测准?assertSame 和 assertEquals 不能混用
它们不是“差不多”,而是语义完全不同的断言。用错一个,测试通过了,bug 却还在那儿。
-
assertEquals(5, $result):松散比较(==),“5”、5.0、5全算通过 -
assertSame(5, $result):严格比较(===),值和类型都得一致,“5” 直接失败 - 如果你的
Calculator::add()声明返回int,就该用assertSame;如果返回的是格式化后的string,才考虑assertEquals - 数组比较别直接
assertEquals,键顺序不同就会失败;改用assertEqualsCanonicalizing()(PHPUnit 9.3+)或先ksort() - 浮点数比较必须加 tolerance 参数:
assertEquals(0.3, 0.1 + 0.2, '', 0.0001)
最常被忽略的一点:expectException() 必须写在触发异常的代码之前,它不是 try-catch,而是声明预期——放错位置,测试就变成“没抛异常也通过”。



















