You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:05:10