控制 PHPUnit 测试执行:仅运行特定命名模式的测试类
在 PHP 项目开发中,随着测试用例数量的增加,我们往往不需要每次执行全部测试。PHPUnit 提供了灵活的测试过滤机制,其中按命名模式筛选测试类是常用的场景,能够帮助我们快速定位和执行目标测试。
为何需要筛选特定命名模式的测试类
实际开发中,测试类通常会按照功能模块、业务逻辑或者测试类型进行命名,比如:
UserModuleTest:用户模块相关测试
OrderServiceTest:订单服务相关测试
IntegrationTest:集成测试类
当只需要验证某个模块的测试,或者仅执行集成测试时,手动指定单个测试类效率较低,通过命名模式批量匹配就非常实用。
使用 --filter 选项按命名模式筛选
PHPUnit 的 --filter 选项支持正则表达式匹配,既可以匹配测试方法名,也可以匹配测试类名。如果要仅运行特定命名模式的测试类,只需要在正则中限定类名规则即可。
基础用法示例
假设项目中的测试类都放在 tests 目录下,我们要运行所有以 Service 结尾的测试类,执行以下命令:
./vendor/bin/phpunit --filter '/Service$/' tests/
这里的 /Service$/ 是正则表达式,$ 表示匹配以 Service 结尾的字符串,刚好对应测试类名。
多模式匹配示例
如果需要同时运行以 Service 结尾和以 Module 结尾的测试类,可以使用正则的或语法:
./vendor/bin/phpunit --filter '/(Service|Module)$/' tests/
在 phpunit.xml 中配置默认筛选规则
如果某个命名模式的测试类需要频繁执行,也可以把筛选规则配置到 phpunit.xml 文件中,避免每次手动输入命令。配置示例如下:
<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="vendor/autoload.php" colors="true"> <testsuites> <testsuite name="default"> <directory>./tests</directory> </testsuite> </testsuites> <filter> <whitelist processUncoveredFilesFromWhitelist="true"> <directory suffix=".php">./src</directory> </whitelist> </filter> <!-- 配置默认筛选规则,仅运行以Test结尾的测试类 --> <groups> </groups> </phpunit>
注意:phpunit.xml 中暂不支持直接配置 --filter 参数,如果需要持久化筛选规则,可以结合 testsuites 的目录配置,把不同命名模式的测试类放到不同目录,再通过指定测试套件执行。
注意事项
--filter 的正则表达式如果没有包裹在
/中,PHPUnit 会默认将其作为子字符串匹配,比如--filter Service会匹配所有类名或方法名中包含 Service 的测试,不仅限于类名结尾。如果测试类有命名空间,匹配时会包含完整的命名空间路径,比如
AppTestsUserService的匹配需要对应正则调整为/AppTestsService$/',注意反斜杠需要转义。筛选仅运行测试类时,该类下的所有测试方法都会被自动执行,不需要额外指定方法名。
代码示例:测试类命名与筛选验证
我们先定义几个不同命名模式的测试类,验证筛选效果:
<?php
// tests/UserServiceTest.php
namespace AppTests;
use PHPUnitFrameworkTestCase;
class UserServiceTest extends TestCase
{
public function testUserCreate()
{
$this->assertTrue(true);
}
}
// tests/OrderModuleTest.php
namespace AppTests;
use PHPUnitFrameworkTestCase;
class OrderModuleTest extends TestCase
{
public function testOrderCreate()
{
$this->assertTrue(true);
}
}
// tests/CommonUtilTest.php
namespace AppTests;
use PHPUnitFrameworkTestCase;
class CommonUtilTest extends TestCase
{
public function testArrayMerge()
{
$this->assertTrue(true);
}
}执行命令 ./vendor/bin/phpunit --filter '/Service$|Module$/' tests/,此时只会运行 UserServiceTest 和 OrderModuleTest 两个类,CommonUtilTest 不会被触发。
通过合理使用命名模式筛选,能够大幅提升测试执行的效率,尤其是在大型项目中,可以快速聚焦目标测试范围,减少不必要的等待时间。