PHPUnit 必须本地安装并配置自动加载,测试类需继承 TestCase 且方法以 test 开头,断言应依返回类型选 assertSame 或 assertEquals,expectException 必须在触发异常前调用。

phpunit 不是“要不要用”的问题,而是你写完一个 Calculator::add() 就该立刻跑一遍测试——否则你连自己改没改坏都不知道。
怎么让 phpunit 命令在项目里直接跑起来
别碰全局安装,也别手动改 PATH。现在标准做法就是 Composer 本地装:
-
composer require --dev phpunit/phpunit ^9.6(PHP 8.0+ 推荐)或^10.5(PHP 8.2+) - 装完立刻验证:
./vendor/bin/phpunit --version,有输出就说明路径和依赖都对 - 顺手加个
composer.json脚本:"test": "phpunit",之后只要composer test就行
常见错误:运行时报 Class 'PHPUnit\Framework\TestCase' not found。这不是 PHPUnit 没装好,而是你忘了在测试文件顶部写 use PHPUnit\Framework\TestCase;,或者没加载自动加载器——确保 phpunit.xml 里有 bootstrap="vendor/autoload.php",或者命令行加 --bootstrap vendor/autoload.php。
CalculatorTest 类为什么必须继承 TestCase,且方法要叫 testAdd
因为 phpunit 是靠这两点识别“哪里是测试”:
立即学习“PHP免费学习笔记(深入)”;
- 类必须继承
PHPUnit\Framework\TestCase,否则它不认这是测试类(哪怕名字带Test) - 方法名必须以
test开头(如testAdd),或用@test注解标记(但前者更直观、少出错) - 方法必须是
public,不能有参数,返回类型建议显式声明为void
如果你写成 addTest() 或 private function testAdd(),phpunit 直接跳过——不会报错,也不会运行,静默失败最坑人。
断言写 assertEquals 还是 assertSame?区别在哪
这俩看着一样,但行为完全不同,选错会导致测试通过了却掩盖真实 bug:
-
assertEquals(5, $result):做松散比较(==),"5"、5.0、5都算通过 -
assertSame(5, $result):做严格比较(===),类型和值都必须一致,"5"就会失败
比如你的 Calculator::add() 声明返回 int,那测试就该用 assertSame;如果返回的是 string 格式化结果,才考虑 assertEquals。别图省事全用 assertEquals,那是给未来埋雷。
测试抛异常的代码,为什么 expectException 必须写在调用前
因为 expectException 是“声明预期”,不是“捕获异常”。它告诉 PHPUnit:“接下来这一行代码,我预期它会抛出这个异常,如果没抛、抛错类型、或者根本没执行到,就算失败。”
典型错误写法:
$this->calculator->divide(10, 0); $this->expectException(\InvalidArgumentException::class); // ❌ 太晚了,异常已经抛出了
正确顺序:
$this->expectException(\InvalidArgumentException::class); $this->calculator->divide(10, 0); // ✅ 异常发生在此处,PHPUnit 正在监听
漏掉这一步,或者顺序颠倒,结果就是 F(Failure),而不是你想要的绿色点。
边界情况容易被忽略:比如异常消息是否也要校验?这时得配合 expectExceptionMessage,否则只校验类型是不够的。



















