是的,Symfony 7.2 新项目预装 symfony/test-pack,PHPUnit 10.x 默认可用,运行 php bin/phpunit 即可执行测试,无需手动安装;但需确保 tests/ 下测试类正确继承 TestCase 并声明命名空间。

PHPUnit 在 Symfony 7.2 中默认可用吗?
是的,symfony/test-pack 已预装在 Symfony 7.2 新项目中,phpunit 命令直接可用,无需手动 composer require --dev phpunit/phpunit。但要注意:它依赖 phpunit/phpunit 10.x(非 11.x),且默认配置绑定的是 tests/ 目录下的 TestCase 类。
常见错误现象:Class "PHPUnit\Framework\TestCase" not found —— 多因误删了 vendor/autoload.php 引用,或在自定义测试类里忘了 use PHPUnit\Framework\TestCase;;也可能是用了 class_alias() 或错误继承了旧版 PHPUnit_Framework_TestCase(已废弃)。
- 运行测试统一用
php bin/phpunit(Symfony 7.2 推荐)或./vendor/bin/phpunit,避免直接调用全局phpunit -
phpunit.xml.dist里bootstrap指向tests/bootstrap.php,后者会加载vendor/autoload.php和 Symfony 测试辅助函数 - 若要测非 Symfony 组件(比如纯工具类),可新建
tests/Unit/Utils/目录,但需确保命名空间与autoload-dev匹配
写第一个 TDD 测试:红阶段失败怎么确认是预期的?
在 tests/Unit/CalculatorTest.php 中写一个未实现方法的测试,比如:
public function testAddReturnsSum(): void
{
$calc = new Calculator();
$this->assertSame(5, $calc->add(2, 3));
}
此时运行 php bin/phpunit tests/Unit/CalculatorTest.php,应看到 Class "App\Calculator" not found 或 Call to undefined method —— 这才是“红”的正确信号。如果报 Fatal error: Uncaught Error: Class "App\Calculator" not found,说明 autoloading 正常,失败源于类缺失;如果报 ParseError 或 TypeError,则可能是 PHP 版本不匹配(Symfony 7.2 要求 PHP 8.2+)或语法错误。
- 别急着创建
Calculator类——TDD 要求先让测试失败,再动手实现 - 确保测试类名以
Test结尾,方法名以test开头,且无参数(否则 PHPUnit 会跳过) - 不要在测试里写
new Calculator()后立刻var_dump()——这破坏自动化断言逻辑,也违背“红”阶段只验证失败意图的原则
Symfony 测试中如何安全模拟服务依赖?
用 createMock() 或 getMockBuilder() 是常规操作,但在 Symfony 7.2 + PHPUnit 10.5+ 下,更推荐结合容器注入和 KernelTestCase 的 self::getContainer() 来获取真实服务实例,仅对**外部副作用**(如 HTTP 客户端、邮件发送器)做 mock。
例如测试一个调用 EmailSender 的订单服务时,应 mock EmailSender,而不是 mock EntityManager —— 因为 Doctrine 实体管理器在测试中可通过事务回滚隔离数据,无需 mock。
- 在
tests/Functional/OrderServiceTest.php中,用$this->createMock(EmailSender::class)替代构造时硬编码 - 别在
setUp()里反复new MockBuilder—— 每个测试方法应独立准备自己的 mock 状态 - 避免 mock
EntityManager或Repository:改用static::getContainer()->get('doctrine.orm.entity_manager')并在tearDown()中执行$em->clear()更可靠 - mock 的
willReturn()返回值必须与方法签名一致,否则 PHPUnit 10.x 会抛Return value typehint mismatch
为什么 php bin/phpunit 跑得慢,且覆盖率报告总为空?
因为 Symfony 7.2 默认禁用代码覆盖率收集,且 phpunit.xml.dist 中 节点被注释掉了。启用后仍为空,大概率是 whitelist 路径没对上 —— Symfony 7.2 的源码在 src/,不是 app/ 或 lib/。
性能影响明显:开启 --coverage-html 会让单个测试耗时增加 3–5 倍,尤其含数据库操作时。这不是 bug,是 Xdebug 或 PCOV 插件采集行级执行信息的必然开销。
- 临时启用覆盖率:取消
phpunit.xml.dist中块的注释,并把放对位置src - CI 环境建议用
phpdbg替代 Xdebug,更快更轻量;本地开发可加--no-coverage加速迭代 - 别信 IDE 内置的“运行覆盖率”按钮——它常忽略
phpunit.xml.dist配置,导致路径错配、结果为空
TDD 在 Symfony 7.2 里真正难的不是写第一个测试,而是守住“红-绿-重构”节奏:每次只动一丁点,测试失败就停,通过才继续,重构前必确认所有测试绿灯亮着。很多人卡在“绿”阶段——写了太多代码想一步到位,结果测试过了但设计已僵化。











