Table of Contents

User defined functions (UDF) are the functions which are created by users as per their own requirement. In order to use a UDF, it is necessary to call the appropriate package file at the beginning of the program. The header file informs the program of the name, type, and number and type of arguments, of all of the functions contained.

import <packageName>

An UDF function is accessed by simply writing the function name, followed by a list of arguments, which represent the information being passed to the function. The arguments must be enclosed in parentheses, and separated by commas: they can be constants, variables, or more complex expressions.

Automation Best Practices: Avoid logics when writing automation test scripts. Every logic is to be maintained in the function libraries and only be called with their name in the test scripts. Every arithmetic calculation, date calculation, string manipulation, etc. should be avoided in the Test scripts rather put them into the functions and use them.

Benefits of User-Defined Functions

  • It can be used in a number of places without rewriting the code.
  • The code can be made less complex and easier to write.
  • Parameters can be passed to the function.
  • Simpler to invoke.

For example:  It is a three steps process to open a URL. First Instantiate a New driver, second Apply an Implicit wait on the driver and third Navigate to URL.  Browser can be any browser; it can be Mozilla, IE or any. It makes sense to create a function for opening a browser which will accept an argument (Browser Type) and it will open that particular browser. This 'Browser Type' argument will be driven from the Test Data sheet. To achieve this few more functions are required.

  1. Function One: openBrowser(int iTestCaseRow), it will return a WebDriver
  2. Function Two: getTestCaseName(String sTestCase), it will return refined Test case name
  3. Function Three: getRowContains(String sTestCaseName, int colNum), it will return the row number of the Test case name from the test data sheet.

How to use it...

  1. Create a new column (Browser) in the Test Data sheet.

TestData_1

Make some entries in the Constant class for the column numbers:

package utility;

public class Constant {

	    public static final String URL = "https://www.store.demoqa.com";

		public static final String Path_TestData = "D://ToolsQA//OnlineStore//src//testData//";

		public static final String File_TestData = "TestData.xlsx";

		//Test Data Sheet Columns

		public static final int Col_TestCaseName = 0;	

		public static final int Col_UserName =1 ;

		public static final int Col_Password = 2;

		public static final int Col_Browser = 3;

	}
  1. Create a 'New Class' by right click on the ‘utility‘ package then select New > Class and name it as Utils. Now create a Static Method for Initiate Browser in the 'Utils' class. This method will have an Argument (TestCase Row) and a Return value (WebDriver).
public class Utils {

        public static WebDriver driver = null;

    public static WebDriver openBrowser(int iTestCaseRow) throws Exception{

        String sBrowserName;

        try{

        sBrowserName = ExcelUtils.getCellData(iTestCaseRow, Constant.Col_Browser);

        if(sBrowserName.equals("Mozilla")){

            driver = new FirefoxDriver();

            Log.info("New driver instantiated");

            driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

            Log.info("Implicit wait applied on the driver for 10 seconds");

            driver.get(Constant.URL);

            Log.info("Web application launched successfully");

            }

        }catch (Exception e){

            Log.error("Class Utils | Method OpenBrowser | Exception desc : "+e.getMessage());

        }

        return driver;

    }

}
  1. To get the Test Case row from the Test data sheet, it is required to get Test Case name, so that it can be searched in the Test Data sheet. Write a function in 'Utils' class to get the Test Case name. Test case name can be easily get by using "this.toString()". This function will return the package name and the class name for e.g. 'automationFramework.UDF_TC@2550036c'. Another function is required to refine the long test case name into UDF_TC.
    public static String getTestCaseName(String sTestCase)throws Exception{

        String value = sTestCase;

        try{

            int posi = value.indexOf("@");

            value = value.substring(0, posi);

            posi = value.lastIndexOf(".");    

            value = value.substring(posi + 1);

            return value;

                }catch (Exception e){

            Log.error("Class Utils | Method getTestCaseName | Exception desc : "+e.getMessage());

            throw (e);

        }
  1. Once Test Case name is captured, it can be used as an Argument for a function that will return the Test case row from the Excel sheet.
public static int getRowContains(String sTestCaseName, int colNum) throws Exception{
	int i;
    try {
	    int rowCount = ExcelWSheet.getLastRowNum();
        for ( i=0 ; i<rowCount; i++){
	        if  (ExcelUtils.getCellData(i,colNum).equalsIgnoreCase(sTestCaseName)){
	            break;
	           }
	        }
        return i;
    }catch (Exception e){
	    Log.error("Class ExcelUtil | Method getRowContains | Exception desc : " + e.getMessage());
        throw(e);
	    }
    }
  1. Create a 'New Class' by right click on the ‘automationFramework‘ package then select TestNG > Create a TestNG Class and name it as UDF_TC.

Note: Take previous executed test case 'TestNG_Framework' and modify its Before Method only. The new test script will look like this:

package automationFramework;

import org.apache.log4j.xml.DOMConfigurator;

import org.openqa.selenium.WebDriver;

import org.testng.annotations.*;

import pageObjects.*;

import utility.*;

import appModules.*;

public class UDF_TC {

    public WebDriver driver;

    private String sTestCaseName;

    private int iTestCaseRow;

    @BeforeMethod

  public void beforeMethod() throws Exception {

         DOMConfigurator.configure("log4j.xml");

         sTestCaseName = this.toString();

         sTestCaseName = Utils.getTestCaseName(this.toString());

        Log.startTestCase(sTestCaseName);

        ExcelUtils.setExcelFile(Constant.Path_TestData + Constant.File_TestData,"Sheet1");

        iTestCaseRow = ExcelUtils.getRowContains(sTestCaseName,Constant.Col_TestCaseName);

        driver = Utils.openBrowser(iTestCaseRow);

        }

    @Test

  public void main() throws Exception {

        SignIn_Action.Execute(driver);

        System.out.println("Login Successfully, now it is the time to Log Off buddy.");

        Home_Page.lnk_LogOut(driver).click();

        Log.info("Click action is performed on Log Out link");

        }

   @AfterMethod

  public void afterMethod() {

        driver.quit();

        }

}

Isn't it easy to call functions rather than writing them again and again and increase code complexity.

TestNG Reports
TestNG Reports
Previous Article
Object Repository
Object Repository
Next Article
Lakshay Sharma
I’M LAKSHAY SHARMA AND I’M A FULL-STACK TEST AUTOMATION ENGINEER. Have passed 16 years playing with automation in mammoth projects like O2 (UK), Sprint (US), TD Bank (CA), Canadian Tire (CA), NHS (UK) & ASOS(UK). Currently, I am working with RABO Bank as a Chapter Lead QA. I am passionate about designing Automation Frameworks that follow OOPS concepts and Design patterns.
Reviewers
Virender Singh's Photo
Virender Singh

Similar Articles

Feedback