Answer
Test Data Management in Large Frameworks
Poor test data management is the #1 cause of brittle automation suites. Here is the professional approach by data type:
Layer 1 — Configuration Data (config.properties)
PROPERTIES
# Environment-specific, never test-specific
baseUrl=https://staging.automateqa.online
apiUrl=https://api.staging.automateqa.online
defaultTimeout=15
browser=chrome
headless=false
Java
public class ConfigManager {
private static Properties config = new Properties();
static {
try (FileInputStream fis = new FileInputStream("src/test/resources/config.properties")) {
config.load(fis);
} catch (IOException e) {
throw new RuntimeException("Cannot load config.properties");
}
}
public static String get(String key) {
return System.getProperty(key, config.getProperty(key));
}
}
// Usage: ConfigManager.get("baseUrl")
Layer 2 — Functional Test Data (Excel / JSON)
Excel via Apache POI:
Java
@DataProvider(name = "loginScenarios")
public Object[][] loginData() throws Exception {
return ExcelUtils.getSheetData("src/test/resources/testdata/TestData.xlsx", "Login");
}
@Test(dataProvider = "loginScenarios")
public void loginTest(String user, String pass, String expectedResult) { ... }
JSON test data (cleaner for complex objects):
JSON
// src/test/resources/testdata/users.json
[
{"username": "admin@test.com", "password": "admin123", "role": "ADMIN"},
{"username": "readonly@test.com", "password": "read456", "role": "VIEWER"},
{"username": "manager@test.com", "password": "mgr789", "role": "MANAGER"}
]
Java
// Read JSON test data
ObjectMapper mapper = new ObjectMapper();
List<UserData> users = mapper.readValue(
new File("src/test/resources/testdata/users.json"),
new TypeReference<List<UserData>>() {});
Layer 3 — Dynamic Test Data via API
Java
public class TestDataFactory {
public static String createTestUser(String role) {
String email = "test_" + System.currentTimeMillis() + "@automateqa.online";
RestAssured
.given()
.header("Authorization", "Bearer " + getAdminToken())
.body("{\"email\":\"" + email + "\",\"role\":\"" + role + "\"}")
.post("/api/users");
return email;
}
public static String createTestOrder(String userId, float amount) {
Response r = RestAssured
.given().header("Authorization", "Bearer " + getAdminToken())
.body("{\"userId\":\"" + userId + "\",\"amount\":" + amount + "}")
.post("/api/orders");
return r.jsonPath().getString("orderId");
}
}
// In test
@BeforeMethod
public void setUp() {
testUserEmail = TestDataFactory.createTestUser("ADMIN");
}
@AfterMethod
public void cleanUp() {
TestDataFactory.deleteUser(testUserEmail); // API cleanup
}
Layer 4 — Database Scripts for Bulk Setup
Java
// For complex test data that''s hard to create via API
public class DatabaseUtils {
private static Connection conn;
public static void insertTestProduct(String name, double price) throws Exception {
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO products (name, price, is_test_data) VALUES (?, ?, true)"
);
ps.setString(1, name);
ps.setDouble(2, price);
ps.executeUpdate();
}
public static void cleanTestData() throws Exception {
conn.createStatement().execute("DELETE FROM products WHERE is_test_data = true");
}
}
Test Data Best Practices
| Rule | Why |
|---|---|
Tag test data with is_test_data=true | Easy to identify and clean up |
| Use unique IDs with timestamps | Avoid conflicts in parallel runs |
| Never depend on pre-existing data | Tests become brittle |
| Clean up in @AfterMethod | Leave environment in known state |
| Never hardcode credentials | Use properties files or env vars |
| Separate data per environment | Staging data ≠ Prod data |
