Bipo K
Bipo K

Reputation: 393

TestNG Reporting, how to quickly identify Retry-d Tests?

Hello: When a @Test fails and a Retry happens, is there a direct way in TestNG to distinguish between a Test that has been Retried and a test that has not been retried - such as through a NG context method or variable?

Some options i have found such as http://www.seleniumeasy.com/testng-tutorials/retry-listener-failed-tests-count-update - but wanted to check if the community has other means and/or recommendations.

Upvotes: 0

Views: 1220

Answers (2)

Krishnan Mahadevan
Krishnan Mahadevan

Reputation: 14746

You can try something like this. The idea is to basically retrieve the retry analyser instance associated with a particular test method and then query its retry count. If its retry count was greater than zero, then that method was retried.

import org.testng.Assert;
import org.testng.IRetryAnalyzer;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

@Listeners(IdentifyRetriedTests.IdentifyingListener.class)
public class IdentifyRetriedTests {
    private static AtomicInteger counter = new AtomicInteger(0);
    private static AtomicInteger anotherCounter = new AtomicInteger(0);

    @Test(retryAnalyzer = Retry.class)
    public void hello() {
        if (counter.incrementAndGet() == 3) {
            Assert.assertTrue(true);
        } else {
            Assert.fail();
        }
    }

    @Test(retryAnalyzer = Retry.class)
    public void anotherHello() {
        if (anotherCounter.incrementAndGet() == 5) {
            Assert.assertTrue(true);
        } else {
            Assert.fail();
        }

    }

    public static class IdentifyingListener extends TestListenerAdapter {

        @Override
        public void onTestSuccess(ITestResult tr) {
            IRetryAnalyzer retry = tr.getMethod().getRetryAnalyzer();
            if (retry instanceof Retry) {
                //Check if the retry analyser's retry count was greater than zero. If yes, then its a retried method
                if (((Retry) retry).getRetryCount() > 0) {
                    tr.setAttribute("retried", true);
                }
            }
        }

        @Override
        public void onFinish(ITestContext testContext) {
            Set<ITestResult> results = new HashSet<>();
            results.addAll(testContext.getFailedTests().getAllResults());
            results.addAll(testContext.getPassedTests().getAllResults());
            for (ITestResult result : results) {
                if (result.getAttribute("retried") != null) {
                    System.err.println(result.getMethod().getMethodName() + "() was retried");
                }
            }
        }
    }

    public static class Retry implements IRetryAnalyzer {
        private AtomicInteger retryCount = new AtomicInteger(0);
        private static int maxRetryCount = 10;

        public boolean retry(ITestResult result) {
            return retryCount.getAndIncrement() < maxRetryCount;
        }

        int getRetryCount() {
            return retryCount.get();
        }
    }
}

Upvotes: 2

juherr
juherr

Reputation: 5740

Currently, there is no easy way to know if the test is a retry or not.

Maybe you can to collect every run methods in a testng listener, and then you can determine if the method was retried if you already find it in the list of run methods.

BTW, you should ask for the feature on http://github.com/cbeust/testng/issues

Upvotes: 1

Related Questions