Data-driven testing is a framework where test input and output data are stored in external data sources like Excel, CSV, or databases. The test scripts execute multiple times with different sets of data, improving test coverage and reducing redundancy.
When designing automated tests, it's essential to separate **common data** (data that applies to multiple test cases or is environment-specific) from **test script data** (data specific to individual test cases). This ensures that the tests are more flexible and easier to maintain.
Common data includes information such as application URLs, credentials, or system settings that multiple test scripts share. For example, the base URL of a website or global login credentials can be considered common data.
Example:
url=https://shariqsp.com
username=admin
password=admin123
Test script data is specific to individual test cases. This includes inputs, expected outputs, or variations in data that change from test to test. For example, different sets of user details when testing a signup form.
Example:
username=testuser1
password=pass1234
email=testuser1@example.com
Hardcoding data directly into test scripts is considered a poor practice because it limits the flexibility, maintainability, and scalability of your test framework. Here’s why:
Hardcoding data makes the test script rigid. If the data changes, you must modify the test script, resulting in unnecessary maintenance. By storing the data in external files like **property files**, **Excel**, or **CSV**, the script remains the same, but the data can change as needed.
If the environment changes (e.g., the URL or credentials for the test server), hardcoded data means you'll need to manually edit every script where this data is present. By separating data into external sources, only the data file needs updating, making it easier to switch between environments.
When expanding test coverage, hardcoded data limits the scalability of your test suite. With external data sources, you can quickly add more data sets without modifying the script logic. For example, you can easily add more rows to an Excel file or database without changing the test scripts.
Consider a scenario where your company changes the password policy, and all passwords need to include special characters. If you have hardcoded passwords in 50 test scripts, each one needs to be modified. This is time-consuming and prone to errors.
Scenario:
You have a login script with hardcoded data:
public class LoginTest {
public void loginTest() {
WebDriver driver = new ChromeDriver();
driver.get("https://shariqsp.com/login");
// Hardcoded credentials
driver.findElement(By.id("username")).sendKeys("testuser");
driver.findElement(By.id("password")).sendKeys("password123");
driver.findElement(By.id("loginButton")).click();
}
}
If the username or password changes, or if you're testing in different environments (staging, production, etc.), you will have to manually update every instance of this hardcoded data. Instead, by using external data, you could simply update the **property file** or **Excel sheet** without touching the script logic.
Data-driven testing offers numerous benefits that improve the efficiency, maintainability, and flexibility of test automation. By separating test data from test logic, data-driven testing enables testers to execute the same test scripts with multiple sets of data, increasing coverage and reducing redundancy.
With data-driven testing, a single test script can be run with multiple data sets, covering a wide range of input scenarios. This significantly improves test coverage as you can test different permutations of input values and edge cases without duplicating test scripts.
Since the test data is stored separately, the same test script can be reused across different test cases. This helps reduce redundancy, as the script remains unchanged while the input data can be modified as needed.
One of the primary benefits of data-driven testing is that if the data changes, there’s no need to update the test script itself. You only need to update the external data sources (such as Excel or property files), making it much easier to maintain and adapt tests when requirements change.
By storing test data externally, data-driven tests can be easily adapted to run across different environments. For example, you can store environment-specific values like URLs, credentials, or settings in external files and switch between them depending on the test environment (e.g., staging, production).
Data-driven testing reduces the need for writing multiple test scripts for similar functionalities. Instead of writing separate tests for each scenario, you can run a single test script with various data sets, saving time and effort.
By running the same script with different data sets, you can generate more comprehensive reports. Each data set’s result is tracked individually, making it easier to identify which scenarios pass or fail.
Data-driven testing allows you to source data from multiple formats such as Excel, CSV, JSON, databases, and more. This flexibility lets you choose the best data storage mechanism for your tests, making it adaptable to various environments and data types.
By externalizing the data, you avoid hardcoding values within your test scripts. This makes your test framework cleaner and more modular, as the test logic is kept separate from the data.
Data-driven testing allows you to run the same test script across multiple browsers (e.g., Chrome, Firefox, Safari) by supplying different browser configurations as data. This ensures that your application works consistently across different browsers.
Example: You can store browser types (e.g., Chrome, Firefox) in an Excel or property file and run the tests with different browsers automatically.
Data-driven testing can handle multiple sets of credentials (e.g., different user roles or permissions). By feeding different credentials from external files like Excel or CSV, you can test your application with multiple users without modifying the script.
Example: You can run the same suite with different roles such as admin, user, or guest, by fetching credentials from the data file and executing the test accordingly.
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>
Data-driven tests can also pull data from relational databases such as MySQL. The Java Database Connectivity (JDBC) API is commonly used to connect and query databases for dynamic data retrieval in test cases.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
TestNG is a powerful testing framework that supports data-driven testing through the `@DataProvider` annotation. By integrating it with external data sources (e.g., Excel, CSV, Property Files), TestNG facilitates running tests with multiple sets of data.
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
</dependency>
Cross-browser and cross-platform testing is essential for ensuring that web applications function correctly across various browsers and operating systems. One effective approach to managing these tests is by utilizing property files. Property files allow you to externalize configuration data, making it easier to manage different settings without hardcoding them in your tests.
Follow these steps to set up and utilize property files for cross-browser and cross-platform testing:
config.properties
to store the configuration settings.# Example config.properties
# Browser Configuration
browser.chrome.path=/path/to/chromedriver
browser.firefox.path=/path/to/geckodriver
browser.safari.path=/path/to/safaridriver
# Browser Options
browser.chrome.options=--headless
browser.firefox.options=--headless
# Platform Configuration
platform.windows=true
platform.mac=false
platform.linux=true
config.properties
file.import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ConfigLoader {
private Properties properties;
public ConfigLoader(String propertyFilePath) {
properties = new Properties();
try {
FileInputStream fileInputStream = new FileInputStream(propertyFilePath);
properties.load(fileInputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public String getProperty(String key) {
return properties.getProperty(key);
}
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class CrossBrowserTest {
public static void main(String[] args) {
ConfigLoader configLoader = new ConfigLoader("config.properties");
String browser = System.getProperty("browser", "chrome"); // Default to Chrome
WebDriver driver;
if (browser.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.gecko.driver", configLoader.getProperty("browser.firefox.path"));
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", configLoader.getProperty("browser.chrome.path"));
driver = new ChromeDriver();
} else {
throw new IllegalArgumentException("Browser not supported: " + browser);
}
// Example test steps
driver.get("https://www.example.com");
System.out.println("Title: " + driver.getTitle());
driver.quit();
}
}
To run your tests on different platforms, you can modify the properties file or pass parameters dynamically at runtime.
config.properties
for different platforms and browsers.# Example command to run a test with a specified browser
mvn test -Dbrowser=firefox
Using property files for cross-browser and cross-platform testing simplifies the management of configuration settings and enhances the flexibility of test execution. This approach enables you to easily switch browsers and platforms without changing your test code, ensuring comprehensive testing across various environments.
Data-driven testing (DDT) is a testing methodology that uses data stored in external files to execute tests. Excel is a popular choice for storing test data due to its ease of use and widespread familiarity. Here are some reasons why we should use Excel in data-driven testing:
Apache POI is a powerful Java library used for reading and writing Microsoft Office documents, including Excel files. It provides a range of APIs to manipulate Excel sheets, allowing you to perform tasks such as reading data from Excel files, writing data back into them, and formatting cells.
This diagram highlights the important classes and interfaces used in the Apache POI library for reading and writing Excel files. It also includes the key methods associated with each class. Arrows indicate inheritance or implementation relationships between interfaces and classes, making the structure clear.
+----------------------+ | Workbook |<-------------+ +----------------------+ | | + createSheet() | | | + getSheetAt() | | | + write() | | +----------------------+ | | | | implements | +----------------------+ +----------------------+ | XSSFWorkbook |<-------------| HSSFWorkbook | +----------------------+ +----------------------+ | (for .xlsx files) | | (for .xls files) | +----------------------+ +----------------------+ | +----------------------+ | Sheet | +----------------------+ | + createRow() | | + getRow() | | + getRowIterator() | +----------------------+ | +------------------+-------------------+ | | +----------------------+ +----------------------+ | XSSFSheet | | HSSFSheet | +----------------------+ +----------------------+ | (for .xlsx sheets) | | (for .xls sheets) | +----------------------+ +----------------------+ | +----------------------+ | Row | +----------------------+ | + createCell() | | + getCell() | | + getCellIterator() | +----------------------+ | +-----------------------+ | Cell | +-----------------------+ | + setCellValue() | | + getStringCellValue()| | + setCellType() | +-----------------------+
createSheet(String name)
: Creates a new sheet with the specified name.getSheetAt(int index)
: Retrieves the sheet at the specified index.write(OutputStream stream)
: Writes the workbook to the specified output stream.Workbook
for `.xlsx` format.Workbook
for `.xls` format.createRow(int rowNum)
: Creates a new row in the sheet at the specified index.getRow(int rowNum)
: Retrieves the row at the specified index.getRowIterator()
: Returns an iterator for the rows in the sheet.Sheet
for `.xlsx` format.Sheet
for `.xls` format.createCell(int columnIndex)
: Creates a new cell in the row at the specified column index.getCell(int columnIndex)
: Retrieves the cell at the specified column index.getCellIterator()
: Returns an iterator for the cells in the row.setCellValue(String value)
: Sets the value of the cell to a String.getStringCellValue()
: Retrieves the cell value as a String.setCellType(CellType type)
: Sets the cell type (e.g., STRING, NUMERIC).The diagram highlights key classes and interfaces in the Apache POI library. Interfaces like Workbook, Sheet, Row, and Cell define the contract for manipulating Excel files, while classes like XSSFWorkbook and HSSFWorkbook provide concrete implementations for working with .xlsx and .xls formats respectively. By understanding the relationship between these interfaces and classes, you can effectively use Apache POI to perform operations on Excel files.
Username | Password | |
---|---|---|
user1 | pass1 | user1@example.com |
user2 | pass2 | user2@example.com |
user3 | pass3 | user3@example.com |
The following program reads user data from an Excel file to automate the user creation process:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class ReadExcel {
public static void main(String[] args) {
String excelFilePath = "user_data.xlsx"; // Path to the Excel file
try (FileInputStream fileInputStream = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fileInputStream)) {
Sheet sheet = workbook.getSheetAt(0); // Get the first sheet
for (Row row : sheet) {
String username = row.getCell(0).getStringCellValue();
String password = row.getCell(1).getStringCellValue();
String email = row.getCell(2).getStringCellValue();
// Use the data for user creation logic
System.out.println("Creating user: " + username + ", Email: " + email);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream
is created to read the Excel file located at the specified path.Workbook
is created using XSSFWorkbook
, which handles .xlsx files.getSheetAt(0)
.IOException
is caught if there are issues reading the file, and the stack trace is printed for debugging.The following program demonstrates how to retrieve a row of data from an Excel sheet based on a condition using Apache POI. In this case, we will retrieve a row where a specific cell in a column matches a given value (e.g., retrieve a row where "Name" equals "John").
// Required imports import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.IOException; public class ReadRowBasedOnCondition { public static void main(String[] args) throws IOException { // Path to Excel file FileInputStream fis = new FileInputStream("path_to_your_file.xlsx"); // Create Workbook instance for .xlsx file Workbook workbook = new XSSFWorkbook(fis); // Get the first sheet (0-indexed) Sheet sheet = workbook.getSheetAt(0); // Iterate over rows for (Row row : sheet) { // Assume column 0 has names, we are looking for "John" Cell cell = row.getCell(0); if (cell.getStringCellValue().equals("John")) { // Print all cell values in the row for (Cell c : row) { System.out.print(c + " "); } System.out.println(); // New line after printing the row } } // Close the workbook and file input stream workbook.close(); fis.close(); } }
XSSFWorkbook
is created to handle `.xlsx` files.getSheetAt(0)
.This program demonstrates how to read all data from a specific column in an Excel sheet. In this case, we will read and print all data from the second column (index 1).
// Required imports import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.IOException; public class ReadColumnData { public static void main(String[] args) throws IOException { // Path to Excel file FileInputStream fis = new FileInputStream("path_to_your_file.xlsx"); // Create Workbook instance for .xlsx file Workbook workbook = new XSSFWorkbook(fis); // Get the first sheet (0-indexed) Sheet sheet = workbook.getSheetAt(0); // Specify the column to read (e.g., column 1 for the second column) int columnIndex = 1; // Iterate over rows and get the cell in the specific column for (Row row : sheet) { Cell cell = row.getCell(columnIndex); if (cell != null) { // Check if cell exists System.out.println(cell); } } // Close the workbook and file input stream workbook.close(); fis.close(); } }
XSSFWorkbook
instance is used to handle `.xlsx` files.getSheetAt(0)
.NullPointerException
for rows that do not have a value in the target column.The following program demonstrates how to read multiple rows of data from an Excel sheet:
public class ReadMultipleData {
public static void main(String[] args) {
String excelFilePath = "user_data.xlsx";
try (FileInputStream fileInputStream = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fileInputStream)) {
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
String username = row.getCell(0).getStringCellValue();
String password = row.getCell(1).getStringCellValue();
String email = row.getCell(2).getStringCellValue();
// Use the data for various test scenarios
System.out.println("Username: " + username + ", Password: " + password + ", Email: " + email);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileInputStream
is created for the Excel file to read data.XSSFWorkbook
object is instantiated to handle the .xlsx file.This program demonstrates how to write user data back into an Excel file:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteExcel {
public static void main(String[] args) {
String excelFilePath = "user_data_output.xlsx";
try (Workbook workbook = new XSSFWorkbook();
FileOutputStream fileOutputStream = new FileOutputStream(excelFilePath)) {
Sheet sheet = workbook.createSheet("User Data");
Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Username");
headerRow.createCell(1).setCellValue("Password");
headerRow.createCell(2).setCellValue("Email");
Row dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue("user4");
dataRow.createCell(1).setCellValue("pass4");
dataRow.createCell(2).setCellValue("user4@example.com");
workbook.write(fileOutputStream);
System.out.println("Data written to Excel file successfully.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
XSSFWorkbook
instance is created to generate a new Excel file.FileOutputStream
is created to specify where to save the Excel file.Below is a program that integrates Selenium with Excel to automate user registration by reading user data and performing actions in a web application:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
public class SeleniumExcelIntegration {
public static void main(String[] args) {
String excelFilePath = "user_data.xlsx";
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); // Specify the path to chromedriver
WebDriver driver = new ChromeDriver();
driver.get("http://example.com/register"); // Navigate to the registration page
try (FileInputStream fileInputStream = new FileInputStream(excelFilePath);
Workbook workbook = new XSSFWorkbook(fileInputStream)) {
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
String username = row.getCell(0).getStringCellValue();
String password = row.getCell(1).getStringCellValue();
String email = row.getCell(2).getStringCellValue();
// Fill in the registration form
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("email")).sendKeys(email);
driver.findElement(By.id("registerBtn")).click(); // Submit the form
// Wait for some time for the registration to complete
Thread.sleep(2000); // Use explicit waits in production code
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
driver.quit(); // Close the browser
}
}
}
driver.get()
.click()
on the register button.driver.quit()
.Selenium script execution with command-line arguments allows you to pass dynamic values such as URLs, browser types, or credentials to your test scripts without hardcoding them into the code. This approach is particularly useful for running tests in different environments or configurations, and it facilitates smooth integration with CI/CD tools like Jenkins.
Using command-line arguments provides flexibility in test execution by allowing you to run the same script with different input values without modifying the script itself. It is especially helpful for the following scenarios:
This example demonstrates how to pass the URL as a command-line argument while executing a Selenium script.
public class SeleniumCommandLineExample {
public static void main(String[] args) {
// Fetch URL from command-line argument
String url = args.length > 0 ? args[0] : "https://defaulturl.com";
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get(url);
// Perform some basic actions (e.g., login)
// Example: driver.findElement(By.id("username")).sendKeys("testuser");
driver.quit();
}
}
To execute this script from the command line, you would use:
java -cp .:selenium-server-standalone.jar SeleniumCommandLineExample https://shariqsp.com
In this example, both the browser type and URL are passed as command-line arguments, enabling cross-browser testing with dynamic URLs.
public class SeleniumCrossBrowserExample {
public static void main(String[] args) {
String browserType = args.length > 0 ? args[0] : "chrome";
String url = args.length > 1 ? args[1] : "https://defaulturl.com";
WebDriver driver;
// Set up browser based on command-line input
if (browserType.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.gecko.driver", "./drivers/geckodriver.exe");
driver = new FirefoxDriver();
} else {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
}
// Launch the URL and perform actions
driver.get(url);
// Example: driver.findElement(By.id("username")).sendKeys("testuser");
driver.quit();
}
}
To execute this script from the command line, use:
java -cp .:selenium-server-standalone.jar SeleniumCrossBrowserExample chrome https://shariqsp.com
In Jenkins, you can configure your jobs to accept parameters dynamically, such as environment URLs, browser types, or credentials. By leveraging command-line arguments, Jenkins can pass these parameters to your Selenium tests, ensuring flexibility and reducing the need to modify test scripts for different environments or configurations.
Here’s how you can configure a Jenkins job to pass parameters to your Selenium tests:
# Example Jenkins build command
java -cp .:selenium-server-standalone.jar SeleniumCrossBrowserExample ${BROWSER_TYPE} ${URL}
Example Setup in Jenkins:
This setup ensures that the same Selenium test can be executed across different browsers and environments without hardcoding the values inside the script, making it more adaptable for CI/CD pipelines.
XML (Extensible Markup Language) is commonly used for storing structured data, including test parameters, configurations, and credentials. In Selenium, you can read data from XML files using a test class approach, which integrates well with testing frameworks like TestNG.
The following XML file stores the test URL, username, and password:
<testdata>
<credentials>
<username>testuser</username>
<password>password123</password>
</credentials>
<environment>
<url>https://shariqsp.com</url>
</environment>
</testdata>
Here’s how you can read the XML data and integrate it into a Selenium test class using TestNG and Java's DOM parser:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class SeleniumXMLTest {
WebDriver driver;
String username, password, url;
@BeforeMethod
public void setup() {
// Read XML data
readXMLData();
// Set up WebDriver
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
}
@Test
public void loginTest() {
// Navigate to URL
driver.get(url);
// Perform login using data from XML
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("loginButton")).click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
public void readXMLData() {
try {
// Load and parse XML file
File file = new File("./testdata.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
// Extract data from XML
username = doc.getElementsByTagName("username").item(0).getTextContent();
password = doc.getElementsByTagName("password").item(0).getTextContent();
url = doc.getElementsByTagName("url").item(0).getTextContent();
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can also use XPath for more precise data extraction from the XML file. Here’s how you can use XPath in the test class:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.File;
public class SeleniumXPathXMLTest {
WebDriver driver;
String username, password, url;
@BeforeMethod
public void setup() {
// Read XML data with XPath
readXMLDataWithXPath();
// Set up WebDriver
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
}
@Test
public void loginTest() {
// Navigate to URL
driver.get(url);
// Perform login using data from XML
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("loginButton")).click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
public void readXMLDataWithXPath() {
try {
// Load and parse XML file
File file = new File("./testdata.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
// Use XPath to extract data
XPath xpath = XPathFactory.newInstance().newXPath();
username = (String) xpath.evaluate("/testdata/credentials/username", doc, XPathConstants.STRING);
password = (String) xpath.evaluate("/testdata/credentials/password", doc, XPathConstants.STRING);
url = (String) xpath.evaluate("/testdata/environment/url", doc, XPathConstants.STRING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
TestNG’s `xmlTest` object allows you to pass parameters from the TestNG XML file directly to your test functions. This approach provides flexibility in managing dynamic data such as URLs, credentials, or other test configurations, without hardcoding them into the test script.
The following TestNG XML file defines parameters (URL, username, and password) for the test execution:
<?xml version="1.0" encoding="UTF-8"?>
<suite name="TestSuite">
<test name="LoginTest">
<parameter name="url" value="https://shariqsp.com"/>
<parameter name="username" value="testuser"/>
<parameter name="password" value="password123"/>
<classes>
<class name="com.test.SeleniumTestWithXmlTest"/>
</classes>
</test>
</suite>
In this example, the `url`, `username`, and `password` parameters are passed from the TestNG XML file to the test function using `xmlTest`.
Here’s how you can access parameters using the `xmlTest` object in a Selenium test class:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.ITestContext;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.testng.xml.XmlTest;
public class SeleniumTestWithXmlTest {
WebDriver driver;
@BeforeMethod
public void setup(XmlTest xmlTest) {
// Fetch URL from the TestNG XML parameters using xmlTest
String url = xmlTest.getParameter("url");
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.get(url);
}
@Test
public void loginTest(XmlTest xmlTest) {
// Fetch username and password from the TestNG XML parameters using xmlTest
String username = xmlTest.getParameter("username");
String password = xmlTest.getParameter("password");
// Perform login
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("loginButton")).click();
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
To run the above test using the TestNG XML file, execute the following command:
java -cp .;testng.jar org.testng.TestNG testng.xml
JDBC (Java Database Connectivity) is an API that enables Java applications to connect and interact with databases. In Selenium, JDBC can be used to interact with databases to perform data-driven testing. You can read data from a database and use it in your tests or validate database entries as part of the testing process.
In this scenario, you will fetch user credentials from a database and use them to log in to a web application using Selenium.
+----+----------+--------------+
| ID | Username | Password |
+----+----------+--------------+
| 1 | testuser | password123 |
| 2 | admin | adminPass |
+----+----------+--------------+
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class SeleniumJDBCExample {
WebDriver driver;
String dbURL = "jdbc:mysql://localhost:3306/testdb"; // Replace with your DB URL
String username = "root"; // DB username
String password = "root"; // DB password
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://shariqsp.com/login");
}
@Test
public void loginWithDBCredentials() {
try {
// Connect to the database
Connection connection = DriverManager.getConnection(dbURL, username, password);
Statement statement = connection.createStatement();
// Execute query to get the user credentials
String query = "SELECT Username, Password FROM users WHERE ID=1";
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.next()) {
String dbUsername = resultSet.getString("Username");
String dbPassword = resultSet.getString("Password");
// Use the data from the database in the Selenium test
driver.findElement(By.id("username")).sendKeys(dbUsername);
driver.findElement(By.id("password")).sendKeys(dbPassword);
driver.findElement(By.id("loginButton")).click();
}
// Close the database connection
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterMethod
public void teardown() {
driver.quit();
}
}
In this scenario, you will create a new user through a web application and verify the user's entry in the database using JDBC.
+----+----------+--------------+
| ID | Username | Password |
+----+----------+--------------+
| 1 | testuser | password123 |
| 2 | admin | adminPass |
| 3 | newuser | newPass123 | <-- New entry created by the test
+----+----------+--------------+
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class SeleniumJDBCValidationExample {
WebDriver driver;
String dbURL = "jdbc:mysql://localhost:3306/testdb"; // Replace with your DB URL
String username = "root"; // DB username
String password = "root"; // DB password
@BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.get("https://shariqsp.com/register");
}
@Test
public void validateUserCreationInDB() {
String newUser = "newuser";
String newPass = "newPass123";
// Fill the registration form to create a new user
driver.findElement(By.id("username")).sendKeys(newUser);
driver.findElement(By.id("password")).sendKeys(newPass);
driver.findElement(By.id("registerButton")).click();
// Validate that the new user was created in the database
try {
// Connect to the database
Connection connection = DriverManager.getConnection(dbURL, username, password);
Statement statement = connection.createStatement();
// Execute query to verify the new user exists in the DB
String query = "SELECT Username FROM users WHERE Username='" + newUser + "'";
ResultSet resultSet = statement.executeQuery(query);
// Assert that the new user exists in the database
Assert.assertTrue(resultSet.next(), "User creation failed. User not found in database.");
// Close the database connection
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterMethod
public void teardown() {
driver.quit();
}
}