如何在PHPUnit+Bitbucket流水线中配置预期失败的测试?
标记预期失败的PHPUnit测试适配Bitbucket流水线方案
针对你提出的需求,这里提供两种无需修改测试断言逻辑的实现方案,完全适配Bitbucket流水线:
方案一:分组+流水线脚本判断(快速实现)
步骤1:给测试标记预期失败分组
给需要标记为“预期失败”的测试添加@group expected-fail注解:
class FooTest { /** * @test * @group expected-fail */ public function bugExploit() { $foo = new Foo(); static::assertEquals(8, $foo->sum(3,5)); } }
步骤2:修改Bitbucket流水线配置
在bitbucket-pipelines.yml中拆分测试执行逻辑,分两步验证:
pipelines: default: - step: name: Execute Tests script: # 1. 先跑所有正常测试,失败则直接终止流水线 - phpunit --exclude-group expected-fail # 2. 单独跑预期失败的测试,捕获输出结果 - phpunit --group expected-fail > test-results.txt 2>&1 # 3. 检查测试是否意外通过:如果输出含"OK",触发流水线失败 - if grep -q "OK" test-results.txt; then echo "预期失败的测试意外通过!" && exit 1; fi # 4. 输出预期失败测试的结果,不影响流水线正常结束 - cat test-results.txt
方案效果
- 满足需求1:预期失败的测试不会让流水线失败
- 满足需求2:代码修复后测试意外通过,流水线会触发失败
- 满足需求3:反转配置只需移除测试的
@group expected-fail,或者修改流水线命令直接跑phpunit即可
方案二:自定义@expectToFail注解(更贴合需求体验)
如果想要更接近你设想的@fail注解效果,可以自定义PHPUnit监听器实现:
步骤1:创建自定义监听器类
class ExpectedFailListener extends PHPUnit\Framework\BaseTestListener { public function endTest(PHPUnit\Framework\Test $test, float $time): void { $annotations = $test->getAnnotations(); // 检测测试方法是否有@expectToFail注解 if (isset($annotations['method']['expectToFail'])) { // 如果测试通过,抛出异常触发失败 if ($test->getStatus() === PHPUnit\Framework\TestStatus::STATUS_PASSED) { throw new PHPUnit\Framework\ExpectationFailedException( "测试标记为@expectToFail但意外通过!" ); } } } }
步骤2:注册监听器到phpunit.xml
<phpunit> <!-- 保留原有配置 --> <listeners> <listener class="ExpectedFailListener" /> </listeners> </phpunit>
步骤3:给测试添加注解
class FooTest { /** * @test * @expectToFail */ public function bugExploit() { $foo = new Foo(); static::assertEquals(8, $foo->sum(3,5)); } }
步骤4:调整流水线脚本
通过脚本处理测试结果,区分“预期失败的测试失败”和“正常测试失败”:
pipelines: default: - step: name: Execute Tests script: # 运行所有测试并捕获结果和退出码 - phpunit > test-results.txt 2>&1 - EXIT_CODE=$? # 检查是否有预期失败的测试意外通过,是则终止流水线 - if grep -q "测试标记为@expectToFail但意外通过!" test-results.txt; then exit 1; fi # 只有正常测试失败时,才保留原退出码终止流水线 - if [ $EXIT_CODE -ne 0 ] && ! grep -q "@expectToFail" test-results.txt; then exit $EXIT_CODE; fi # 输出所有测试结果 - cat test-results.txt
方案效果
- 完全贴合你想要的注解标记体验
- 无需修改测试的断言逻辑
- 反转配置只需移除测试的
@expectToFail注解即可
内容的提问来源于stack exchange,提问作者klutt
相关产品推荐
相关产品推荐

