只需装对、跑通、写准三步:用composer require --dev安装,vendor/bin/phpunit验证,require_once 'vendor/autoload.php'确保加载;断言选assertsame或assertequals需严格匹配类型;expectexception须紧邻抛异常代码。

别被“完整指南”吓住——你只需要装对、跑通、写准三步,就能让 PHPUnit 为你干活。其他全是锦上添花。
phpunit 命令找不到?直接用 vendor/bin/phpunit
这不是 PATH 没配好,是误信了“全局安装更方便”的过时说法。新版 Composer 默认不把 phpunit 放进全局 bin,硬加 --global 容易和项目 PHP 版本冲突。
- 在项目根目录执行
composer require --dev phpunit/phpunit ^10.5(PHP 8.2+ 推荐) - 验证安装:
./vendor/bin/phpunit --version,有输出就说明路径和依赖都对 - 顺手加一行到
composer.json的"scripts"里:"test": "phpunit",之后只要composer test就行 - 别用
phpunit tests/CalculatorTest.php这种写法跑单个文件——它绕过phpunit.xml配置,autoload 和 bootstrap 很可能失效
Class 'PHPUnit\Framework\TestCase' not found 怎么办
这不是 PHPUnit 没装,是自动加载没触发。TestCase 类根本没被引入,use 语句再对也没用。
- 测试文件顶部必须有
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,大小写都不能错
assertEquals 还是 assertSame?选错就等于没测
它们不是“差不多”,而是语义完全不同的断言。用错一个,测试通过了,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,而是声明预期。PHPUnit 靠这个标记来判断“接下来这行,我盯住了”。写晚了,就等于没声明。
- 正确顺序:
$this->expectException(\InvalidArgumentException::class);→ 然后立刻调用会抛异常的代码 - 如果中间插了别的逻辑(比如日志、变量赋值),PHPUnit 就认为“异常没在这儿抛”,直接报错
- 别在
try-catch里写expectException——它俩逻辑冲突,PHPUnit 不认 - 想验证异常消息?用
$this->expectExceptionMessage('must be positive');,但必须跟expectException在同一作用域内
最常被忽略的其实是测试隔离:没清空全局状态、没重置静态属性、没关闭资源句柄,一个测试失败可能连带搞垮后面十个。setup/teardown 不是可选项,是保命线。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











