Tuesday, June 30, 2015

SELENIUM : RERUN FAILED TEST SCRIPTS USING TESTNG


There will be situations where we will re run failed automation test scripts and get the positive results upon rerun.


What if we have some utility which will rerun each failed test script..?


Yes.., We have it..we can automate rerunning test scripts scenario using IRetryAnalyzer and IRetryAnalyzer  interfaces of TestNG.


Create a Java class say RetryTest which implements IRetryAnalyzer  interface of TestNG.


Here, retryDemo() is my test method which will reexecuted on failure.
We are overriding retry() method of IRetryAnalyzer interface.
We are overriding transform() method of IAnnotationTransformer interface.


import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.annotations.ITestAnnotation;
import org.testng.annotations.Test;

 public class RetryTest implements IRetryAnalyzer,IAnnotationTransformer {

     private int retryCount = 0;
    private int maxRetryCount = 1; //Mention how many times we want to rerun the failed test case.
   
    @Override
    public boolean retry(ITestResult result) {
     if (retryCount < maxRetryCount) {
      System.out.println("Retrying test " + result.getName()
        + " with status " + getResultStatusName(result.getStatus())
        + " for the " + (retryCount + 1) + " time(s).");
      retryCount++;
      return true;
     }
     return false;
    }
   

     @Override
    public void transform(ITestAnnotation testannotation, Class testClass,
      Constructor testConstructor, Method testMethod)    {
     IRetryAnalyzer retry = testannotation.getRetryAnalyzer();

      if (retry == null)    {
      testannotation.setRetryAnalyzer(AutomationFrameWork.class);
     }

     }
   
   
    @Test(retryAnalyzer = RetryTest.class)
    public void retryDemo() throws Exception {
     WebDriver driver = new FirefoxDriver();
     driver.get("https://www.google.co.in");
     WebElement searchBtn = driver.findElement(By.xpath("//input[@name='btnK']"));//get webelement of search button on Google Home Page.
     String actual = searchBtn.getAttribute("value");//Value: Google Search
     String expected = "Yahoo";
     Assert.assertEquals(actual, expected);
   
    }
   
    public String getResultStatusName(int status) {
     String resultName = null;
     if (status == 1)
      resultName = "SUCCESS";
     if (status == 2)
      resultName = "FAILURE";
     if (status == 3)
      resultName = "SKIP";
     return resultName;
    }

   

 }


Thats all folks…!


You have to just modify the test method: retryDemo() based upon need and enjoy.


Happy Coding !



4 comments:

  1. Doesn't work in TestNG 6.8.7...The failed test is skipping instead of re-running.

    ReplyDelete
    Replies
    1. It should work. Although I will try with this specific version of TestNG- 6.8.7. Meanwhile provide more details, if you can, It may help in debugging your issue.

      Delete
    2. Thank you.. It actually working now. I had some other code issues. Do you have nay blog regarding "TestNG Tests Run Count after Retry" ... I run through Jenkins via maven-surefire-plugin.

      Thanks,

      Delete
    3. Hello, I don't have any blog for Test run count after retry. I will write the same. But I would have handled this scenario by putting below codes in @Aftermethod :



      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]);
      }
      }
      }


      where context is of type ITestContext and a parameter in teardown method with @AfterMethod annotation. Here I am removing failed one in all executions of particular test script. Just try it and let me know if it helped.

      Delete