Search This Blog

Friday, April 10, 2015

Retry Logic in TestNG to re-run failed test-cases | TestNG | Jenkins

1| Assume you have a class file with 10 Methods [@Test]
2| Lets say one got failed due to Network issue
3| The class file, RetryAnalyzer will make the failed test-case to re-run with desired count; But, it display errors for all the test failures during re-run.
4| You are ought to add a Listener class, RetryTestListener; it will print the failure only once.
5| If the test got passed in the final count, failure exception won't be thrown in the console.


Test Class

@BeforeTest
public void setUp()
 {
 driver = new FirefoxDriver();
 baseUrl = "https://www.google.co.in";
 driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
 }

@Test(retryAnalyzer=RetryAnalyzer.class)
public void test01() throws Exception
 {
 driver.get(baseUrl + "/");
 String save = driver.findElement(By.id("als")).getText();
 System.out.println(save);
        // Assert.fail();
 Assert.assertEquals(save, "qwerty");
 }

**************************************************************

RetryAnalyzer.java

Create a Java class, 'RetryAnalyzer' inside the same package and paste the following snippet with minor edits.

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class RetryAnalyzer implements IRetryAnalyzer  {
private int count = 0;
private int maxCount = 4; // set your count to re-run test
protected Logger log;
private static Logger testbaseLog;

static {
    PropertyConfigurator.configure("test-config/log4j.properties");
    testbaseLog = Logger.getLogger("TestclassName");
}

public RetryAnalyzer()
{
    testbaseLog.trace( " ModeledRetryAnalyzer constructor " + this.getClass().getName() );
    log = Logger.getLogger("TestclassName");
}

@Override
public boolean retry(ITestResult result) {
    testbaseLog.trace("running retry logic for  '"
            + result.getName()
            + "' on class " + this.getClass().getName() );
        if(count < maxCount) {                    
                count++;                                   
                return true;
        }
        return false;
}
}

******************************************************

RetryTestListener.java

import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

import testng.TestCase;
import java.util.HashSet;
import java.util.Set;

/**
 * Listens for failed tests that need to be rerun.
 */
public class RetryTestListener extends TestListenerAdapter  {
    private static final  Logger logger = Logger.getLogger(RetryTestListener.class);
    private static int count = 1;
    private static final int maxCount = 7;

    @Override
    public void onTestFailure(ITestResult tr) {  
        tr.setAttribute("retry.count", count);
        tr.setAttribute("retry.maxCount", maxCount);
        boolean cond = false;
        if(count < maxCount) {
            count++;
            try  {
                if(TestCase.driver == null)  {
                    tr.setStatus(ITestResult.SKIP);
                    return;
                }
              
                 cond = true;
                if(cond)  {
                    tr.setAttribute("retry", true);
                }
            } catch(Exception e)  {
                logger.error("COULD NOT RETRY TESTCASE: "+e.getMessage());
            }

        } else  {
            logger.error("Number of retries expired.");
            tr.setStatus(ITestResult.FAILURE);
            // reset count
            count = 1;
        }
        super.onTestFailure(tr);
    }

    @Override
    public void onTestSuccess(ITestResult tr) {
        super.onTestSuccess(tr);
        count = 1;
    }
   
   
    @Override
    public void onFinish(ITestContext context) {
        for (int i = 0; i < context.getAllTestMethods().length; i++) {
            if (context.getAllTestMethods()[i].getCurrentInvocationCount() == 2) {
                if (context.getFailedTests().getResults(context.getAllTestMethods()[i]).size() == 2
                        || context.getPassedTests().getResults(context.getAllTestMethods()[i]).size() == 1) {
                    context.getFailedTests().removeResult(context.getAllTestMethods()[i]);
                }
            }
        }
       
    }
   
    private Set findDuplicates(Set listContainingDuplicates) {
        Set toRemove = new HashSet();
        Set testSet = new HashSet();
       
        for(ITestResult test : listContainingDuplicates)  {
            if (!testSet.add(test.getMethod())) {
                toRemove.add(test.getMethod());
            }   
        }
        return toRemove;
       
    }
}

No comments:

My Profile

My photo
can be reached at 09916017317