使用testng listener实现测试用例失败重跑功能

我们通过重写testng的retry方法和transform方法来实现用例失败重跑的功能。

首先添加两个文件

TestngRetry.java

public class TestngRetry implements IRetryAnalyzer {
	private static Logger logger = Logger.getLogger(TestngRetry.class);
	private static int maxRetryCount = 3;
	private int retryCount = 1;

	@Override
	public boolean retry(ITestResult result) {
		if (retryCount <= maxRetryCount) {
			String message = "Running retry for '" + result.getName()
					+ "' on class " + this.getClass().getName() + " Retrying "
					+ retryCount + " times";
			logger.info(message);
			Reporter.setCurrentTestResult(result);
			Reporter.log("RunCount=" + (retryCount + 1));
			retryCount++;
			return true;
		}
		return false;
	}
}

RetryListener.java

public class RetryListener implements IAnnotationTransformer {
	@Override
	public void transform(ITestAnnotation annotation, Class testClass,
			Constructor testConstructor, Method testMethod) {
		IRetryAnalyzer retry = annotation.getRetryAnalyzer();
		if (retry == null) {
			annotation.setRetryAnalyzer(TestngRetry.class);
		}
	}
}

添加以上两个文件之后,有两种方法可以使用我们的listener进行监听:

  • 在Test标签中添加retryAnalyzer属性
@Test(retryAnalyzer = com.xxx.retry.RetryListener.class)
  • 在testng.xml文件中配置listener
<test name="test1">
	<listeners>
		<listener class-name="com.xxx.retry.RetryListener" />
	</listeners>
	<classes>
		<class name="com.xxx.test.NewTest" />
	</classes>
</test>

做完上面的工作,我们就可以实现失败重跑的功能了。但是,每次用例重跑之后,每次失败的结果也记录在运行结果中了,测试结果中运行的用例数增加了,不利于我们查看测试结果。因此,我们还需要把重复的用例去掉。
这个我们通过重写TestListenerAdapter中的onFinish方法实现:

TestngListener.java

public class TestngListener extends TestListenerAdapter {
	private static Logger logger = Logger.getLogger(TestngListener.class);
	@Override
	public void onFinish(ITestContext testContext) {
		super.onFinish(testContext);

		// List of test results which we will delete later
		ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>();
		// collect all id's from passed test
		Set<Integer> passedTestIds = new HashSet<Integer>();
		for (ITestResult passedTest : testContext.getPassedTests()
				.getAllResults()) {
			logger.info("PassedTests = " + passedTest.getName());
			passedTestIds.add(getId(passedTest));
		}

		Set<Integer> failedTestIds = new HashSet<Integer>();
		for (ITestResult failedTest : testContext.getFailedTests()
				.getAllResults()) {
			logger.info("failedTest = " + failedTest.getName());
			int failedTestId = getId(failedTest);

			// if we saw this test as a failed test before we mark as to be
			// deleted
			// or delete this failed test if there is at least one passed
			// version
			if (failedTestIds.contains(failedTestId)
					|| passedTestIds.contains(failedTestId)) {
				testsToBeRemoved.add(failedTest);
			} else {
				failedTestIds.add(failedTestId);
			}
		}

		// finally delete all tests that are marked
		for (Iterator<ITestResult> iterator = testContext.getFailedTests()
				.getAllResults().iterator(); iterator.hasNext();) {
			ITestResult testResult = iterator.next();
			if (testsToBeRemoved.contains(testResult)) {
				logger.info("Remove repeat Fail Test: " + testResult.getName());
				iterator.remove();
			}
		}

	}

	private int getId(ITestResult result) {
		int id = result.getTestClass().getName().hashCode();
		id = id + result.getMethod().getMethodName().hashCode();
		id = id
				+ (result.getParameters() != null ? Arrays.hashCode(result
						.getParameters()) : 0);
		return id;
	}
}

把listener添加到testng.xml中,当前testng.xml为:

<test name="test1">
	<listeners>
		<listener class-name="com.xxx.retry.RetryListener" />
		<listener class-name="com.xxx.retry.TestngListener" />
	</listeners>
	<classes>
		<class name="com.xxx.test.NewTest" />
	</classes>
</test>

OK,结束。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
TestNG支持测试用例的依赖关系,即一个测试方法依赖于另外一个测试方法的执行结果。如果一个测试方法依赖于另外一个测试方法,那么在运行测试套件时,TestNG会先运行被依赖的测试方法,如果该方法执行成功,再运行依赖该方法的测试方法。这样能够确保测试方法的执行顺序和依赖关系。 TestNG提供了两种方式来实现测试用例的依赖: 1. 通过dependsOnMethods属性实现依赖关系 在@Test注解中使用dependsOnMethods属性来指定被依赖的测试方法。例如: ``` @Test public void loginTest() { //登录测试逻辑 } @Test(dependsOnMethods = {"loginTest"}) public void searchTest() { //搜索测试逻辑 } ``` 在上面的例子中,searchTest方法依赖于loginTest方法,因此在运行测试套件时,TestNG会先运行loginTest方法,如果该方法执行成功,再运行searchTest方法。 2. 通过dependsOnGroups属性实现依赖关系 在@Test注解中使用dependsOnGroups属性来指定被依赖的测试组。例如: ``` @Test(groups = {"login"}) public void loginTest() { //登录测试逻辑 } @Test(groups = {"search"}, dependsOnGroups = {"login"}) public void searchTest() { //搜索测试逻辑 } ``` 在上面的例子中,searchTest方法依赖于一个名为“login”的测试组,而loginTest方法属于该测试组。因此在运行测试套件时,TestNG会先运行loginTest方法,如果该方法执行成功,再运行searchTest方法。 使用dependsOnMethods或dependsOnGroups属性可以方便地实现测试用例的依赖关系,但是需要注意依赖关系的正确性和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值