Answer
Data-Driven Testing with TestNG + Excel
Add Apache POI Dependency (pom.xml)
XML
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
Test Data File (LoginData.xlsx)
CODE
| scenario | email | password | expected |
|----------|-------------------|-----------|-----------------|
| valid | alice@test.com | Pass@123 | Dashboard |
| invalid | wrong@test.com | wrongpass | Invalid credentials |
| empty | | | Email is required|
| locked | locked@test.com | Pass@123 | Account locked |
ExcelUtil — Read Data
Java
// utils/ExcelUtil.java
public class ExcelUtil {
public static Object[][] readData(String filePath, String sheetName) throws IOException {
FileInputStream fis = new FileInputStream(filePath);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
XSSFSheet sheet = workbook.getSheet(sheetName);
int rowCount = sheet.getLastRowNum(); // skip header row
int colCount = sheet.getRow(0).getLastCellNum();
Object[][] data = new Object[rowCount][colCount];
for (int row = 1; row <= rowCount; row++) { // start from row 1 (skip header)
XSSFRow currentRow = sheet.getRow(row);
for (int col = 0; col < colCount; col++) {
XSSFCell cell = currentRow.getCell(col);
data[row - 1][col] = getCellValue(cell);
}
}
workbook.close();
fis.close();
return data;
}
private static String getCellValue(XSSFCell cell) {
if (cell == null) return "";
switch (cell.getCellType()) {
case STRING: return cell.getStringCellValue();
case NUMERIC: return String.valueOf((long) cell.getNumericCellValue());
case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
default: return "";
}
}
}
Test Using @DataProvider
Java
// tests/LoginTest.java
public class LoginTest extends BaseTest {
// DataProvider reads from Excel
@DataProvider(name = "loginData")
public Object[][] getLoginData() throws IOException {
return ExcelUtil.readData(
"src/test/resources/testdata/LoginData.xlsx", "Login");
}
@Test(dataProvider = "loginData")
public void testLogin(String scenario, String email, String pass, String expected) {
LoginPage login = new LoginPage(DriverManager.getDriver());
login.login(email, pass);
if (scenario.equals("valid")) {
Assert.assertTrue(
new DashboardPage(DriverManager.getDriver()).isLoaded(),
"Dashboard not loaded for: " + scenario);
} else {
Assert.assertEquals(login.getError(), expected,
"Error message mismatch for: " + scenario);
}
}
}
Inline DataProvider (Without Excel)
Java
// For simple cases — hardcoded in test class
@DataProvider(name = "searchTerms")
public Object[][] searchData() {
return new Object[][] {
{ "Selenium", true },
{ "Cypress", true },
{ "xyznothing", false },
};
}
@Test(dataProvider = "searchTerms")
public void testSearch(String term, boolean hasResults) {
homePage.search(term);
Assert.assertEquals(resultsPage.hasResults(), hasResults);
}
DataProvider from JSON (Alternative to Excel)
Java
@DataProvider(name = "usersJson")
public Object[][] getUsersFromJson() throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(new File("src/test/resources/testdata/users.json"));
Object[][] data = new Object[root.size()][3];
for (int i = 0; i < root.size(); i++) {
data[i][0] = root.get(i).get("email").asText();
data[i][1] = root.get(i).get("password").asText();
data[i][2] = root.get(i).get("role").asText();
}
return data;
}
Parallel DataProvider Execution
Java
// Run each data row in parallel (separate threads)
@DataProvider(name = "loginData", parallel = true)
public Object[][] parallelData() throws IOException {
return ExcelUtil.readData("testdata/login.xlsx", "Sheet1");
}
// Requires ThreadLocal WebDriver in DriverManager!
