Home > front end >  Set tests to retry based on parameter in .xml?
Set tests to retry based on parameter in .xml?

Time:08-02

I'm trying to implement test retries on failure, right now I've added IRetryListener which I managed to get working. The issue I am facing is, that when developing new tests locally the retry is kicking off each time the tests fail, and we really don't need the retry kicking off while we are developing new tests locally. Is there a way to set a parameter or flag that would allow us to only have retries when it is set to true?

Annotation Transformer

package IRetryAnalyzer;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

        public class AnnotationTransformer implements IAnnotationTransformer {
            @Override
            public void transform(ITestAnnotation annotation, 
                                                        Class testClass, 
                                                        Constructor testConstructor,
                                                        Method testMethod) {
                annotation.setRetryAnalyzer(RetryAnalyzer.class);
            }
        }

Retry Interface

package IRetryAnalyzer;
import org.testng.ITestResult;

public interface IRetryAnalyzer {

  /**
   * Returns true if the test method has to be retried, false otherwise.
   *
   * @param result The result of the test method that just ran.
   * @return true if the test method has to be retried, false otherwise.
   */
  public boolean retry(ITestResult result);
}

RetryAnalyzer

package IRetryAnalyzer;

import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

import pages.BaseClass;

public class RetryAnalyzer extends BaseClass implements IRetryAnalyzer {
    private int count = 0;
    private static int maxTry = 3;
    @Override
    public boolean retry(ITestResult iTestResult) {
        if (!iTestResult.isSuccess()) {                      //Check if test not succeed
            if (count < maxTry) {                            //Check if maxtry count is reached
                count  ;                                     //Increase the maxTry count by 1
               logg.info("Test Failed: Retrying");
                iTestResult.setStatus(ITestResult.FAILURE);  //Mark test as failed
                return true;                                 //Tells TestNG to re-run the test
            } else {
                logg.info("Test Failed: Max retry count reached. Flagged as failed");
                iTestResult.setStatus(ITestResult.FAILURE);  //If maxCount reached,test marked as failed
            }
        } else {
            iTestResult.setStatus(ITestResult.SUCCESS);      //If test passes, TestNG marks it as passed
        }
        return false;
    }
}

BaseClass

package pages;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;

/**
 * 
 *
 *
 */

public class BaseClass {
    public static Logger logg = Logger.getLogger(BaseClass.class.getName());

    protected static WebDriver driver;

    String ***** = "*****";

    // *****
    String ***** = "*****";

    // *****
    String ***** = "*****";
    
    //*****
    String ***** ="*****";

    /**
     * This function will execute before each Test tag in testng.xml
     * 
     * @param browser
     * @throws MalformedURLException
     * @throws Exception
     */
    @BeforeMethod
    @Parameters({ "browser", "environmentURL", "grid", "retry"})
    public void setup(String browserName, String env, String grid) throws MalformedURLException {
            
        logg.info("Initializing browser setup");
        logg.info(browserName   " Session has started");

        if (grid.equalsIgnoreCase("true")) {
            logg.info("Remote session intiated");
            DesiredCapabilities capabilities = new DesiredCapabilities();
            capabilities.setCapability("browserName", "chrome");
            capabilities.setCapability("platform", "linux");
            driver = new RemoteWebDriver(new URL(MvnProperties.gridUrl), capabilities);
        } else {

            if (browserName.equalsIgnoreCase("Firefox")) {
                // create firefox instance
                System.setProperty("webdriver.gecko.driver", "/usr/local/bin/geckodriver");
                driver = new FirefoxDriver();
            }
            // Check if parameter passed as 'chrome'
            if (browserName.equalsIgnoreCase("Chrome")) {

                // set path to chromedriver.exe
                System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver");
                // create chrome instance
                driver = new ChromeDriver();
            }

            // Check if parameter passed as 'chrome'
            if (browserName.equalsIgnoreCase("Chrome Dev")) {

                // set path to chromedriver.exe
                System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriverdev");
                // create chrome instance
                driver = new ChromeDriver();
            }
            // Check if parameter passed as 'Edge'
            if (browserName.equalsIgnoreCase("Edge")) {
                // set path to Edge.exe
                System.setProperty("webdriver.edge.driver", "/usr/local/bin/msedgedriver");
                // create Edge instance
                driver = new EdgeDriver();
            }
        }
        logg.info("Waiting for browser to load");
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        logg.info("Maximizing window");
        driver.manage().window().maximize();
        logg.info("******** Browser has been initialized********");

        // directs test to environment

        logg.info("Opening "   env   " environment");
        driver.get("*****");
        logg.info(env   " was reached");

        if (env.equals("stage")) {
            logg.info("Opening "   env   " environment");
            driver.get("*****");
            logg.info(env   " was reached");
            logg.info("*****");
            logg.info("*****");
            logg.info("*****");
            logg.info("*****");
            logg.info("*****");
        }

        if (env.equals("prod")) {
            logg.info("Opening "   env   " environment");
            driver.get("*****");
            logg.info(env   " was reached");
        }
    }

    /**
     * This function will execute after each Test tag in testng.xml
     * 
     * @param none
     * @throws Exception
     */
    @AfterMethod
    public void teardown() {
        logg.info("****** Test Finished: Beginning teardown ******");
        logg.info("Closing browser");
        driver.quit();
    }
}

XML File - I was hoping to be able to achieve this through the parameter retry as shown below, however I was running into issues trying to find the correct way to handle something like this on google

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestSuite">
    <listeners>
        <listener class-name="listeners.TestListener" />
    </listeners>
    <listeners>
        <listener class-name="IRetryAnalyzer.RetryAnalyzer"/>
  </listeners>
     <listeners>
        <listener class-name="IRetryAnalyzer.AnnotationTransformer"/>
  </listeners>

    <test name="LoginTests">

        <parameter name="browser" value="Chrome" />
        <parameter name="grid" value="false" />
        <parameter name="environmentURL" value="stage" />
        <parameter name="retry" value="true" />

        <classes>
            <class name="tests.LoginTests">
            </class>
        </classes>
    </test>
</suite>

CodePudding user response:

You can do this by having your retry analyser set only when a JVM argument is set to true. Your modified annotation transformer would look like below. This implementation would wire in your retry analyser only when it finds a JVM argument named retry.tests set to true. So whenever you would like the retry analyser to be enabled, then pass in the JVM argument -Dretry.tests=true

package IRetryAnalyzer;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class AnnotationTransformer implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor,Method testMethod) {
        if (Boolean.getBoolean("retry.tests")) {
            annotation.setRetryAnalyzer(RetryAnalyzer.class);
        }
       
    }
}
  • Related