testng-data-driven
Use when implementing data-driven tests with TestNG DataProviders, factory methods, and parameterization patterns.
What this skill does
# TestNG Data-Driven Testing
Master TestNG data-driven testing including DataProviders, Factory patterns, and parameterization for comprehensive test coverage. This skill covers techniques for testing with multiple data sets efficiently.
## Overview
Data-driven testing separates test logic from test data, enabling a single test method to run against multiple inputs. TestNG provides powerful features for data-driven testing through DataProviders, Factory methods, and XML parameterization.
## DataProvider Basics
### Simple DataProvider
```java
import org.testng.annotations.*;
import static org.testng.Assert.*;
public class SimpleDataProviderTest {
@DataProvider(name = "numbers")
public Object[][] provideNumbers() {
return new Object[][] {
{1, 2, 3},
{4, 5, 9},
{0, 0, 0},
{-1, 1, 0}
};
}
@Test(dataProvider = "numbers")
public void testAddition(int a, int b, int expected) {
assertEquals(a + b, expected);
}
}
```
### DataProvider with Single Values
```java
public class SingleValueDataProviderTest {
@DataProvider(name = "validEmails")
public Object[][] provideValidEmails() {
return new Object[][] {
{"[email protected]"},
{"[email protected]"},
{"[email protected]"},
{"[email protected]"}
};
}
@Test(dataProvider = "validEmails")
public void testValidEmail(String email) {
assertTrue(isValidEmail(email), "Email should be valid: " + email);
}
private boolean isValidEmail(String email) {
return email != null && email.matches("^[\\w+.-]+@[\\w.-]+\\.[a-zA-Z]{2,}$");
}
}
```
## Advanced DataProvider Patterns
### DataProvider in Separate Class
```java
// DataProviders class
public class TestDataProviders {
@DataProvider(name = "userData")
public static Object[][] provideUserData() {
return new Object[][] {
{"john", "[email protected]", 25},
{"jane", "[email protected]", 30},
{"bob", "[email protected]", 22}
};
}
@DataProvider(name = "loginCredentials")
public static Object[][] provideLoginCredentials() {
return new Object[][] {
{"admin", "admin123", true},
{"user", "user456", true},
{"invalid", "wrong", false}
};
}
}
// Test class using external DataProvider
public class UserTest {
@Test(dataProvider = "userData", dataProviderClass = TestDataProviders.class)
public void testUserCreation(String name, String email, int age) {
User user = new User(name, email, age);
assertNotNull(user);
assertEquals(user.getName(), name);
assertEquals(user.getEmail(), email);
assertEquals(user.getAge(), age);
}
@Test(dataProvider = "loginCredentials", dataProviderClass = TestDataProviders.class)
public void testLogin(String username, String password, boolean expectedSuccess) {
boolean result = authService.login(username, password);
assertEquals(result, expectedSuccess);
}
}
```
### DataProvider with Method Context
```java
import org.testng.ITestContext;
import org.testng.annotations.*;
import java.lang.reflect.Method;
public class ContextAwareDataProviderTest {
@DataProvider(name = "contextAwareData")
public Object[][] provideContextAwareData(ITestContext context, Method method) {
String testName = method.getName();
String suiteName = context.getSuite().getName();
System.out.println("Providing data for: " + testName + " in suite: " + suiteName);
if (testName.contains("Admin")) {
return new Object[][] {
{"admin", "ADMIN_ROLE"},
{"superadmin", "SUPER_ADMIN_ROLE"}
};
} else {
return new Object[][] {
{"user1", "USER_ROLE"},
{"user2", "USER_ROLE"}
};
}
}
@Test(dataProvider = "contextAwareData")
public void testAdminAccess(String username, String role) {
// Test admin access
}
@Test(dataProvider = "contextAwareData")
public void testUserAccess(String username, String role) {
// Test user access
}
}
```
### Parallel DataProvider
```java
public class ParallelDataProviderTest {
@DataProvider(name = "parallelData", parallel = true)
public Object[][] provideParallelData() {
return new Object[][] {
{"Test 1"},
{"Test 2"},
{"Test 3"},
{"Test 4"},
{"Test 5"},
{"Test 6"},
{"Test 7"},
{"Test 8"},
{"Test 9"},
{"Test 10"}
};
}
@Test(dataProvider = "parallelData")
public void testParallel(String data) {
System.out.println(Thread.currentThread().getName() + " - " + data);
// Tests run in parallel threads
}
}
```
### Iterator DataProvider
```java
import java.util.Iterator;
import java.util.Arrays;
public class IteratorDataProviderTest {
@DataProvider(name = "iteratorData")
public Iterator<Object[]> provideIteratorData() {
// Useful for large datasets - generates data on demand
return Arrays.asList(
new Object[]{"data1", 1},
new Object[]{"data2", 2},
new Object[]{"data3", 3}
).iterator();
}
@Test(dataProvider = "iteratorData")
public void testWithIterator(String name, int value) {
assertNotNull(name);
assertTrue(value > 0);
}
}
```
### Lazy DataProvider for Large Datasets
```java
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LazyDataProviderTest {
@DataProvider(name = "lazyData")
public Iterator<Object[]> provideLazyData() {
return new Iterator<Object[]>() {
private int current = 0;
private final int max = 1000;
@Override
public boolean hasNext() {
return current < max;
}
@Override
public Object[] next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
// Generate data on demand
return new Object[]{
"User_" + current,
"user" + current + "@example.com",
current++
};
}
};
}
@Test(dataProvider = "lazyData")
public void testLargeDataset(String name, String email, int id) {
assertNotNull(name);
assertTrue(email.contains("@"));
}
}
```
## Factory Pattern
### Basic Factory
```java
import org.testng.annotations.*;
public class FactoryTest {
private String browser;
@Factory
public static Object[] createInstances() {
return new Object[] {
new FactoryTest("chrome"),
new FactoryTest("firefox"),
new FactoryTest("safari")
};
}
public FactoryTest(String browser) {
this.browser = browser;
}
@Test
public void testHomePage() {
System.out.println("Testing home page on: " + browser);
}
@Test
public void testLoginPage() {
System.out.println("Testing login page on: " + browser);
}
}
```
### Factory with DataProvider
```java
public class FactoryWithDataProviderTest {
private String username;
private String role;
@Factory(dataProvider = "userRoles")
public FactoryWithDataProviderTest(String username, String role) {
this.username = username;
this.role = role;
}
@DataProvider(name = "userRoles")
public static Object[][] provideUserRoles() {
return new Object[][] {
{"admin", "ADMIN"},
{"manager", "MANAGER"},
{"user", "USER"},
{"guest", "GUEST"}
};
}
@Test
public void testUserPermRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.