Selenium

Selenium-Generate and Execute Run Time testNG xml

TestNG is a popular testing framework designed to simplify a broad range of testing needs, from unit testing to integration testing for Java that allows users to perform automated testing for web applications.
Selenium, on the other hand, is a popular automation testing tool that enables users to automate web browsers. Combining these two tools allows developers to create powerful automated tests for their web applications.

Challenge

We used to execute the tests in batch , groups or module wise using the TestNG xml suite. for that we need to create different TestNG xml files for different test suites , also we need to pass that TestNG file name to pom.xml for execution. Managing different TestNG files for different tests suite is challenging and tedious task .

Solution

We have a solution by generating and executing a single TestNG file at runtime through the code. we can use an excel file to list all the tests and group tests module wise , smoke or regression test or by selecting the Test Execution Flag column to ‘Yes’ for test which you want to execute.

below is the maven java project structure and packages :

Use below TestNGXmlUtil java class for generating and running of testNG xml at run time as per the module given as an input or tests selected for execution from excel file.

package com.qautomation.utility;

import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.testng.TestNG;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

public class TestNGXmlUtil {
	
	public static Map<Integer,List<String>> mapTestDetail = new HashMap<Integer,List<String>>();	
	
	public static void executeTestSuiteRunner(String moduleName)
	{	
		String sTestSuiteName ="QAUTO";

		if(!moduleName.equals("")){
	    	getTestDetailsFromExcel(moduleName);
	    }else{
	    	getTestDetailsFromExcel();
	    }
	    
	    executeRunTimeTestNGXml(sTestSuiteName);		
	}
	
	public static void createRunTimeTestNGXmlFile(XmlSuite TestSuite)
	{	
		//Create TestNG Xml file
		String RootFolderPath = System.getProperty("user.dir");		
		try
		{
			FileWriter objFile = new FileWriter(RootFolderPath+"\\testng_tests_suite.xml");
			objFile.write(TestSuite.toXml());
			objFile.close();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public static void getTestDetailsFromExcel(String sTestModule)
	{
		try
		{
			String sExcelFilePath ="";
			String sTestClassName = "";
			String sTestModuleName = "";
			String sTestPackageName = "";
			
			sExcelFilePath = System.getProperty("user.dir")+"\\TestData\\Tests_Suite_Runner.xlsx";
			
			FileInputStream Fis = new FileInputStream(sExcelFilePath);
			XSSFWorkbook book=new XSSFWorkbook(Fis);
			
			XSSFSheet sheet= book.getSheetAt(0);			
			int totalRows = sheet.getLastRowNum();
			
			for( int r=1, count=1;r<=totalRows;r++)
			{
				sTestModuleName = "";
				sTestPackageName = "";
				sTestClassName = "";
				
				sTestModuleName  = sheet.getRow(r).getCell(1).toString();
				
				if(sTestModuleName.equalsIgnoreCase(sTestModule))
				{
					sTestPackageName = sheet.getRow(r).getCell(2).toString();
					sTestClassName  = sheet.getRow(r).getCell(3).toString();
					mapTestDetail.put(count, Arrays.asList(sTestPackageName,sTestClassName));
					count++;
				}
			}
			book.close();			
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	public static void getTestDetailsFromExcel()
	{
		try
		{
			String sExcelFilePath ="";
			String sTestClassName = "";
			String sTestPackageName = "";
			String sTestExecutionFlag ="";
			
			sExcelFilePath = System.getProperty("user.dir")+"\\TestData\\Tests_Suite_Runner.xlsx";
			
			FileInputStream Fis = new FileInputStream(sExcelFilePath);
			XSSFWorkbook book=new XSSFWorkbook(Fis);
			XSSFSheet sheet= book.getSheetAt(0);
			
			int totalRows = sheet.getLastRowNum();
			for( int r=1, count=1;r<=totalRows;r++)
			{
				sTestExecutionFlag = "";
				sTestPackageName = "";
				sTestClassName = "";
				
				sTestExecutionFlag  = sheet.getRow(r).getCell(4).toString();
				if(sTestExecutionFlag.equalsIgnoreCase("Y"))
				{
					sTestPackageName = sheet.getRow(r).getCell(2).toString();
					sTestClassName = sheet.getRow(r).getCell(3).toString();
					mapTestDetail.put(count, Arrays.asList(sTestPackageName,sTestClassName));
					count++;
				}
			}
			book.close();			
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	public static void executeRunTimeTestNGXml(String TestSuiteName)
	{
		try
		{
			TestNG objTestNG = new TestNG();
			XmlSuite objTestSuite = new XmlSuite();
			objTestSuite.setName(TestSuiteName);
			
			List<XmlTest> lisXmlTests = new ArrayList<XmlTest>();
			
			for(Map.Entry<Integer, List<String>> map:mapTestDetail.entrySet())
			{
				XmlTest objTest = new XmlTest(objTestSuite);
				objTest.setName(map.getValue().get(1));
				objTest.setXmlClasses(Arrays.asList(new XmlClass(map.getValue().get(0)+"."+map.getValue().get(1))));
				lisXmlTests.add(objTest);
			}
			objTestSuite.setTests(lisXmlTests);
			List<XmlSuite> TestSuites = new ArrayList<XmlSuite>();
			TestSuites.add(objTestSuite);
			objTestNG.setXmlSuites(TestSuites);
			createRunTimeTestNGXmlFile(objTestSuite);
			objTestNG.run();			
			
		}
		catch(NullPointerException e)
		{
			e.printStackTrace();
		}
	}
	

}

Create a TestSuiteRunner Class to call the function executeTestSuiteRunner from TestNGXmlUtil.

Here ‘Demo’ is the module name so it will pick up all the tests having ‘Demo’ as module and create a runtime testNG xml ‘testng_tests_runner.xml’

When you passing nothing then code will pickup all the tests having Test Execution Flag column value to ‘Yes’.

Note- You can do customization as per your project need and also manage these input from property file.

package com.qautomation.runner;
import org.testng.annotations.Test;
import com.qautomation.utility.TestNGXmlUtil;

public class TestSuiteRunner {	
	
	@Test
	public void executeTestRunner()
	{			
		TestNGXmlUtil.executeTestSuiteRunner("Demo");		
	}		
	
}

Create a TestNG xml for calling the TestSuiteRunner class

Use above testng_tests_runner.xml file in your pom.xml for execution through maven.

Execute testng_tests_runner.xml by selecting testNG , you will see both tests QAUTO_Demo_Test1 and QAUTO_Demo_Test2 get executed by creating a run time testNG file i.e testng_tests_suite.xml

dynamically created run time testNG xml file – testng_tests_suite.xml

For full code with customization as per your project requirement . Kindly contact us.

Categories: Selenium

Leave a Reply