Create flexible test frameworks that separate test logic from test data
Support CSV, JSON, XML, Excel, and database data sources
Generate tests dynamically based on data configurations
Implement data versioning, validation, and environment management
Data-driven testing separates test logic from test data, enabling the same test to run with multiple data sets. This approach increases test coverage while reducing code duplication and maintenance effort.
// Generic data provider interface public interface TestDataProvider { List<TestData> getTestData(String testName); TestData getTestData(String testName, String dataId); void validateData(TestData data); } // CSV Data Provider public class CsvDataProvider implements TestDataProvider { private String dataDirectory; public CsvDataProvider(String dataDirectory) { this.dataDirectory = dataDirectory; } @Override public List<TestData> getTestData(String testName) { String filePath = dataDirectory + "/" + testName + ".csv"; List<TestData> testDataList = new ArrayList<>(); try (CSVReader reader = new CSVReader(new FileReader(filePath))) { String[] headers = reader.readNext(); String[] values; while ((values = reader.readNext()) != null) { TestData testData = new TestData(); for (int i = 0; i < headers.length; i++) { testData.put(headers[i], values[i]); } testDataList.add(testData); } } catch (IOException e) { throw new RuntimeException("Failed to read CSV data: " + filePath, e); } return testDataList; // JSON Data Provider public class JsonDataProvider implements TestDataProvider { private ObjectMapper objectMapper = new ObjectMapper(); public JsonDataProvider(String dataDirectory) { String filePath = dataDirectory + "/" + testName + ".json"; try { JsonNode rootNode = objectMapper.readTree(new File(filePath)); JsonNode testDataArray = rootNode.get("testData"); for (JsonNode dataNode : testDataArray) { dataNode.fields().forEachRemaining(entry -> testData.put(entry.getKey(), entry.getValue().asText())); throw new RuntimeException("Failed to read JSON data: " + filePath, e); // Database Data Provider public class DatabaseDataProvider implements TestDataProvider { private Connection connection; public DatabaseDataProvider(Connection connection) { this.connection = connection; String query = "SELECT * FROM test_data WHERE test_name = ? AND active = true"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, testName); ResultSet rs = stmt.executeQuery(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); while (rs.next()) { for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnName(i); String value = rs.getString(i); testData.put(columnName, value); } catch (SQLException e) { throw new RuntimeException("Failed to read database data for test: " + testName, e); }
// Data-driven test class public class UserRegistrationTest extends BaseTest { private TestDataProvider dataProvider; @BeforeClass public void setUp() { String dataSource = System.getProperty("data.source", "json"); String dataDir = System.getProperty("data.directory", "src/test/resources/data"); switch (dataSource) { case "csv": dataProvider = new CsvDataProvider(dataDir); break; case "database": dataProvider = new DatabaseDataProvider(getDatabaseConnection()); default: dataProvider = new JsonDataProvider(dataDir); @DataProvider(name = "registrationData") public Object[][] getRegistrationData() { List<TestData> testDataList = dataProvider.getTestData("userRegistration"); Object[][] data = new Object[testDataList.size()][1]; for (int i = 0; i < testDataList.size(); i++) { data[i][0] = testDataList.get(i); return data; @Test(dataProvider = "registrationData") public void testUserRegistration(TestData testData) { // Extract test data String firstName = testData.getString("firstName"); String lastName = testData.getString("lastName"); String email = testData.getString("email"); String password = testData.getString("password"); String expectedResult = testData.getString("expectedResult"); // Execute test RegistrationPage registrationPage = new RegistrationPage(driver); registrationPage.fillRegistrationForm(firstName, lastName, email, password); if ("success".equals(expectedResult)) { Assert.assertTrue(registrationPage.isRegistrationSuccessful()); } else { Assert.assertTrue(registrationPage.hasErrorMessage()); String expectedError = testData.getString("expectedError"); Assert.assertEquals(registrationPage.getErrorMessage(), expectedError); 🏗️ Environment-Specific Data Management ✅ Environment Data Manager public class EnvironmentDataManager { private String environment; private Map<String, TestDataProvider> dataProviders; public EnvironmentDataManager() { this.environment = System.getProperty("test.environment", "dev"); initializeDataProviders(); private void initializeDataProviders() { dataProviders = new HashMap<>(); // Environment-specific data directories String baseDir = "src/test/resources/data/" + environment; dataProviders.put("json", new JsonDataProvider(baseDir + "/json")); dataProviders.put("csv", new CsvDataProvider(baseDir + "/csv")); // Environment-specific database connections if ("prod".equals(environment)) { dataProviders.put("database", new DatabaseDataProvider(getProdConnection())); dataProviders.put("database", new DatabaseDataProvider(getTestConnection())); public TestData getUserData(String userType) { TestDataProvider provider = getDataProvider(); List<TestData> users = provider.getTestData("users"); return users.stream() .filter(user -> userType.equals(user.getString("userType"))) .findFirst() .orElseThrow(() -> new RuntimeException("User type not found: " + userType)); public TestData getEnvironmentConfig() { return provider.getTestData("config", environment); private TestDataProvider getDataProvider() { return dataProviders.get(dataSource); ← Module 4: Page Object Patterns Module 5 Complete! 🎉 Module 6: Parallel Execution →
public class EnvironmentDataManager { private String environment; private Map<String, TestDataProvider> dataProviders; public EnvironmentDataManager() { this.environment = System.getProperty("test.environment", "dev"); initializeDataProviders(); private void initializeDataProviders() { dataProviders = new HashMap<>(); // Environment-specific data directories String baseDir = "src/test/resources/data/" + environment; dataProviders.put("json", new JsonDataProvider(baseDir + "/json")); dataProviders.put("csv", new CsvDataProvider(baseDir + "/csv")); // Environment-specific database connections if ("prod".equals(environment)) { dataProviders.put("database", new DatabaseDataProvider(getProdConnection())); dataProviders.put("database", new DatabaseDataProvider(getTestConnection())); public TestData getUserData(String userType) { TestDataProvider provider = getDataProvider(); List<TestData> users = provider.getTestData("users"); return users.stream() .filter(user -> userType.equals(user.getString("userType"))) .findFirst() .orElseThrow(() -> new RuntimeException("User type not found: " + userType)); public TestData getEnvironmentConfig() { return provider.getTestData("config", environment); private TestDataProvider getDataProvider() { return dataProviders.get(dataSource); ← Module 4: Page Object Patterns Module 5 Complete! 🎉 Module 6: Parallel Execution →