Data-driven testing in Selenium relies on various libraries and tools to read and manage data from external sources. Here are some of the commonly used tools and libraries:
Property files are simple text files that store key-value pairs. They are widely used to manage configuration data such as environment URLs, login credentials, and other reusable data across tests. Property files allow test scripts to be more flexible by externalizing data, avoiding hardcoding.
# Example config.properties file
url=https://shariqsp.com
username=testuser
password=password123
Apache POI is a Java library that allows you to read and write Excel files (.xls and .xlsx). It is commonly used in data-driven testing to handle test data stored in Excel files.
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
OpenCSV is a lightweight library that simplifies reading and writing CSV files in Java. It is an excellent choice for handling test data stored in CSV format.
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.4</version>
</dependency>
Jackson is a powerful Java library for parsing JSON data. It is helpful when dealing with test data stored in JSON format and can easily convert JSON to Java objects and vice versa.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
In Selenium test automation, a **Generic Utility** refers to a reusable class or method that abstracts common tasks or functionalities into a generic framework. These utilities help reduce redundancy, improve code reusability, and streamline automation processes. By organizing commonly used functions into utilities, test scripts become cleaner, more maintainable, and easier to manage.
There are several common categories of generic utilities in Selenium, each serving a different purpose in simplifying Selenium scripts:
A common utility class is for managing browser operations such as launching a browser, maximizing the window, and closing the browser.
package com.utility;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class BrowserUtility {
public static WebDriver driver;
// Method to launch the browser
public static WebDriver launchBrowser(String browserType, String url) {
if (browserType.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
} else if (browserType.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.gecko.driver", "./drivers/geckodriver.exe");
driver = new FirefoxDriver();
}
// Maximize the browser window
driver.manage().window().maximize();
// Navigate to the specified URL
driver.get(url);
return driver;
}
// Method to close the browser
public static void closeBrowser() {
if (driver != null) {
driver.quit();
}
}
}
Another common utility is for implementing **explicit waits** to manage dynamic elements and ensure that Selenium waits for elements to load before interacting with them.
package com.utility;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class WaitUtility {
// Method to wait for an element to be clickable
public static WebElement waitForElementToBeClickable(WebDriver driver, By locator, int timeout) {
WebDriverWait wait = new WebDriverWait(driver, timeout);
return wait.until(ExpectedConditions.elementToBeClickable(locator));
}
// Method to wait for an element to be visible
public static WebElement waitForElementToBeVisible(WebDriver driver, By locator, int timeout) {
WebDriverWait wait = new WebDriverWait(driver, timeout);
return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
}
}
This utility helps read data from Excel files, making it useful for data-driven testing.
package com.utility;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class ExcelUtility {
// Method to fetch data from Excel
public static String getExcelData(String filePath, String sheetName, int rowNumber, int cellNumber) {
String value = "";
try {
FileInputStream file = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheet(sheetName);
Row row = sheet.getRow(rowNumber);
value = row.getCell(cellNumber).getStringCellValue();
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
}
Generic utilities can be easily integrated into your Selenium test automation framework by creating utility packages that contain utility classes. For example, you can have a `com.utility` package that contains classes like `BrowserUtility`, `WaitUtility`, and `ExcelUtility`.
import com.utility.BrowserUtility;
import com.utility.WaitUtility;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class SampleTest {
WebDriver driver;
@BeforeMethod
public void setup() {
// Launch browser and navigate to URL using BrowserUtility
driver = BrowserUtility.launchBrowser("chrome", "https://shariqsp.com");
}
@Test
public void testLogin() {
// Wait for login button to be clickable using WaitUtility
WebElement loginButton = WaitUtility.waitForElementToBeClickable(driver, By.id("loginButton"), 10);
loginButton.click();
}
@AfterMethod
public void teardown() {
// Close the browser using BrowserUtility
BrowserUtility.closeBrowser();
}
}
Organizing your Selenium project with a clear and well-defined package structure is crucial for the maintainability, scalability, and readability of your test automation framework. This is particularly important when integrating generic utilities into your project. A proper structure helps ensure that test code, utility functions, configurations, and reports are well-organized and easily manageable.
The following package structure is commonly used in Selenium automation projects to implement **Generic Utilities**:
A **Maven** project follows a standardized directory layout, making it easy for developers to collaborate and manage dependencies. Below is a diagram that explains the typical Maven project structure for Selenium automation:
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.3.0</version>
</dependency>
</dependencies>
Here’s a breakdown of what each package might contain in a real-world scenario for an e-commerce application: