TestNg IRetryAnalyzer和IAnnotationTransformer作用

自动重试失败的测试用例,减少由于环境问题或偶发性错误导致的测试失败。

TestNg

在 TestNG 中,IRetryAnalyzerIAnnotationTransformer 是两个非常强大的接口,用于自定义和扩展测试的执行行为。

IRetryAnalyzer

IRetryAnalyzer 接口允许你定义重试逻辑,当一个测试方法失败时,可以根据自定义的条件重新运行该测试。这个功能非常有用,可以处理偶发性故障,如由于临时环境问题导致的失败。

使用示例

实现 IRetryAnalyzer 接口:
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class RetryAnalyzer implements IRetryAnalyzer {
    private int retryCount = 0;
    private static final int maxRetryCount = 3;

    @Override
    public boolean retry(ITestResult result) {
        if (retryCount < maxRetryCount) {
            retryCount++;
            return true;
        }
        return false;
    }
}
将 RetryAnalyzer 应用于测试方法:
import org.testng.annotations.Test;

public class TestClass {

    @Test(retryAnalyzer = RetryAnalyzer.class)
    public void testMethod() {
        System.out.println("Executing test method");
        // 模拟失败
        assert false;
    }
}

IAnnotationTransformer

IAnnotationTransformer 接口允许在运行时修改测试方法的注解属性。这对于在测试运行时动态更改测试行为非常有用,例如在某些条件下改变超时设置或数据提供者。

使用示例

实现 IAnnotationTransformer 接口:
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class AnnotationTransformer implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
        // 在运行时修改超时属性
        if ("testMethod".equals(testMethod.getName())) {
            annotation.setRetryAnalyzer(RetryAnalyzer.class);
        }
    }
}
配置 TestNG 使用 AnnotationTransformer:
  • 在 testng.xml 文件中添加 AnnotationTransformer:
 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
    <listeners>
        <listener class-name="your.package.AnnotationTransformer" />
    </listeners>
    <test name="Test">
        <classes>
            <class name="your.package.TestClass" />
        </classes>
    </test>
</suite>

通过这种方式,你可以动态修改测试方法的注解属性。



Junit4 & 5

maven实现

在 Maven 中,可以结合 JUnit 和 Maven Surefire 插件来实现测试失败后的重试机制。Maven Surefire 插件是用于运行单元测试和集成测试的插件,可以通过配置和自定义扩展来支持测试重试。

<project>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.22.2</version>
                    </dependency>
                </dependencies>
                <configuration>
                <!-- IGNORE TEST-->
                  <!--  <testFailureIgnore>true</testFailureIgnore> -->
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
</project>

maven -DrerunFailingTestsCount=3
*test case

import org.junit.Test;
import static org.junit.Assert.assertTrue;

public class MyTests {

    private static int counter = 0;

    @Test
    public void testMethod() {
        System.out.println("Executing testMethod, attempt: " + (counter + 1));
        counter++;
        assertTrue("Test failed, retrying...", counter >= 3);
    }
}

在这个示例中,testMethod 会在前两次失败,并在第三次重试时成功。

自定义重试逻辑

如果你需要更复杂的重试逻辑,可以结合 JUnit 规则或扩展机制来实现。在这里,我们使用 JUnit 4 的规则实现一个自定义的重试逻辑。

创建自定义重试规则

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class RetryRule implements TestRule {
    private int retryCount;

    public RetryRule(int retryCount) {
        this.retryCount = retryCount;
    }

    @Override
    public Statement apply(Statement base, Description description) {
        return new RetryStatement(base, retryCount);
    }

    private static class RetryStatement extends Statement {
        private final Statement base;
        private final int retryCount;

        public RetryStatement(Statement base, int retryCount) {
            this.base = base;
            this.retryCount = retryCount;
        }

        @Override
        public void evaluate() throws Throwable {
            Throwable caughtThrowable = null;

            for (int i = 0; i < retryCount; i++) {
                try {
                    base.evaluate();
                    return;
                } catch (Throwable t) {
                    caughtThrowable = t;
                    System.out.println("Retrying test, attempt " + (i + 1));
                }
            }
            throw caughtThrowable;
        }
    }
}

在测试类中使用重试规则

import org.junit.Rule;
import org.junit.Test;

public class MyTests {

    @Rule
    public RetryRule retryRule = new RetryRule(3);

    @Test
    public void testMethod() {
        System.out.println("Executing testMethod");
        // Simulate a failure
        assert false;
    }

    @Test
    public void anotherTestMethod() {
        System.out.println("Executing anotherTestMethod");
        // Simulate a passing test
        assert true;
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值