CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-tngtech-java--junit-dataprovider

A TestNG-like dataprovider runner for JUnit having a simplified syntax compared to all the existing JUnit features.

Pending
Overview
Eval results
Files

utilities.mddocs/

Utility Methods and Helper Classes

This document covers the utility classes and helper methods that simplify creating and manipulating data provider arrays.

Required Imports

import com.tngtech.java.junit.dataprovider.DataProviders;
import static com.tngtech.java.junit.dataprovider.DataProviders.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

DataProviders Utility Class

The DataProviders class provides static helper methods for creating data provider arrays with less boilerplate code.

public class DataProviders {
    
    /**
     * Create Object array containing all given arguments.
     * @param args arguments to include in array
     * @return Object array containing all args
     */
    public static Object[] $(Object... args)
    
    /**
     * Create array of Object arrays from given arrays.
     * @param args Object arrays to combine
     * @return array of Object arrays
     */
    public static Object[][] $$(Object[]... args)
    
    /**
     * Create dataprovider test for each argument.
     * @param args arguments to wrap individually
     * @return array containing Object arrays for each single argument
     */
    public static Object[][] testForEach(Object... args)
    
    /**
     * Create dataprovider test for each element in Iterable.
     * @param args Iterable to convert
     * @return array containing Object arrays for each element
     * @deprecated since 1.12.0 - Iterable can be returned directly
     */
    @Deprecated
    public static <T> Object[][] testForEach(Iterable<T> args)
    
    /**
     * Create dataprovider test for each enum value.
     * @param enumClass enum Class to get values from
     * @return array containing Object arrays for each enum value
     */
    public static <E extends Enum<E>> Object[][] testForEach(Class<E> enumClass)
    
    /**
     * Create cross product of two data providers.
     * @param rows1 first dataprovider data
     * @param rows2 second dataprovider data  
     * @return cross product combining all row combinations
     */
    public static Object[][] crossProduct(Object[][] rows1, Object[][] rows2)
}

Basic Array Creation

The $() and $$() methods provide a concise syntax for creating data provider arrays:

import static com.tngtech.java.junit.dataprovider.DataProviders.*;

@DataProvider
public static Object[][] testData() {
    return $$(
        $("hello", 5, true),
        $("world", 5, true), 
        $("", 0, false),
        $("testing", 7, true)
    );
}

// Equivalent to:
@DataProvider  
public static Object[][] testDataVerbose() {
    return new Object[][] {
        new Object[] { "hello", 5, true },
        new Object[] { "world", 5, true },
        new Object[] { "", 0, false },
        new Object[] { "testing", 7, true }
    };
}

Single Parameter Tests

Use testForEach() when each data item should be a separate test case:

@DataProvider
public static Object[][] stringValues() {
    return testForEach("alpha", "beta", "gamma", "delta");
}

// Equivalent to:
// return new Object[][] { {"alpha"}, {"beta"}, {"gamma"}, {"delta"} };

@Test
@UseDataProvider("stringValues")
public void testSingleString(String value) {
    assertNotNull(value);
    assertTrue(value.length() > 0);
}

Enum Testing

Test all values of an enum easily:

enum Priority { LOW, MEDIUM, HIGH, CRITICAL }

@DataProvider
public static Object[][] allPriorities() {
    return testForEach(Priority.class);
}

// Equivalent to:
// return new Object[][] { {LOW}, {MEDIUM}, {HIGH}, {CRITICAL} };

@Test
@UseDataProvider("allPriorities")
public void testPriorityHandling(Priority priority) {
    assertNotNull(priority);
    // Test priority-specific logic
}

Iterable Conversion (Deprecated)

While still available, direct Iterable return is now preferred:

// Deprecated approach
@DataProvider
public static Object[][] fromList() {
    List<String> items = Arrays.asList("item1", "item2", "item3");
    return testForEach(items);
}

// Preferred approach (since 1.12.0)
@DataProvider
public static List<String> fromListDirect() {
    return Arrays.asList("item1", "item2", "item3");
}

Cross Product Combinations

Generate all combinations of two data sets:

@DataProvider
public static Object[][] userTypes() {
    return $$($("admin"), $("user"), $("guest"));
}

@DataProvider  
public static Object[][] permissions() {
    return $$($("read"), $("write"), $("delete"));
}

@DataProvider
public static Object[][] userPermissionCombinations() {
    return crossProduct(userTypes(), permissions());
}

// Results in:
// [["admin", "read"], ["admin", "write"], ["admin", "delete"],
//  ["user", "read"], ["user", "write"], ["user", "delete"], 
//  ["guest", "read"], ["guest", "write"], ["guest", "delete"]]

@Test
@UseDataProvider("userPermissionCombinations")
public void testUserPermissions(String userType, String permission) {
    // Test all user type and permission combinations
}

Advanced Utility Patterns

Dynamic Data Generation

Combine utilities with dynamic data generation:

@DataProvider
public static Object[][] dynamicRangeData() {
    List<Object[]> data = new ArrayList<>();
    for (int i = 1; i <= 5; i++) {
        data.add($("value" + i, i * 10, i % 2 == 0));
    }
    return data.toArray(new Object[0][]);
}

// Or using testForEach with computed values
@DataProvider
public static Object[][] computedValues() {
    List<Integer> values = IntStream.range(1, 10)
                                  .boxed()
                                  .collect(Collectors.toList());
    return testForEach(values);
}

Complex Cross Products

Generate complex combinations with multiple dimensions:

@DataProvider
public static Object[][] browsers() {
    return testForEach("chrome", "firefox", "safari");
}

@DataProvider
public static Object[][] resolutions() {  
    return testForEach("1920x1080", "1366x768", "390x844");
}

@DataProvider
public static Object[][] platforms() {
    return testForEach("windows", "mac", "linux");
}

@DataProvider
public static Object[][] allEnvironmentCombinations() {
    Object[][] browserRes = crossProduct(browsers(), resolutions());
    return crossProduct(browserRes, platforms());
}

@Test
@UseDataProvider("allEnvironmentCombinations")
public void testAcrossEnvironments(String browser, String resolution, String platform) {
    // Test with all browser/resolution/platform combinations
}

Filtering and Transforming Data

Create specialized data sets:

@DataProvider
public static Object[][] positiveNumbers() {
    return testForEach(1, 5, 10, 100, 1000);
}

@DataProvider
public static Object[][] negativeNumbers() {
    return testForEach(-1, -5, -10, -100, -1000);
}

@DataProvider
public static Object[][] allNumbers() {
    return crossProduct(
        $$($("positive")), 
        positiveNumbers()
    ).concat(crossProduct(
        $$($("negative")),
        negativeNumbers()
    ));
}

// Manual concatenation helper
private static Object[][] concat(Object[][] array1, Object[][] array2) {
    Object[][] result = new Object[array1.length + array2.length][];
    System.arraycopy(array1, 0, result, 0, array1.length);
    System.arraycopy(array2, 0, result, array1.length, array2.length);
    return result;
}

Integration with External Data

Combine utilities with external data sources:

File-Based Data

@DataProvider
public static Object[][] fromCSVFile() throws IOException {
    List<Object[]> data = new ArrayList<>(); 
    try (BufferedReader reader = Files.newBufferedReader(Paths.get("test-data.csv"))) {
        String line;
        while ((line = reader.readLine()) != null) {
            String[] parts = line.split(",");
            data.add($(parts[0], Integer.parseInt(parts[1]), Boolean.parseBoolean(parts[2])));
        }
    }
    return data.toArray(new Object[0][]);
}

Database Data

@DataProvider
public static Object[][] fromDatabase() {
    // Assuming you have a database connection
    List<Object[]> data = new ArrayList<>();
    String sql = "SELECT name, age, active FROM test_users";
    
    try (PreparedStatement stmt = connection.prepareStatement(sql);
         ResultSet rs = stmt.executeQuery()) {
        while (rs.next()) {
            data.add($(rs.getString("name"), rs.getInt("age"), rs.getBoolean("active")));
        }
    } catch (SQLException e) {
        throw new RuntimeException("Failed to load test data", e);
    }
    
    return data.toArray(new Object[0][]);
}

JSON Data

@DataProvider
public static Object[][] fromJSONFile() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    JsonNode root = mapper.readTree(new File("test-data.json"));
    
    List<Object[]> data = new ArrayList<>();
    for (JsonNode item : root) {
        data.add($(
            item.get("name").asText(),
            item.get("value").asInt(),
            item.get("enabled").asBoolean()
        ));
    }
    
    return data.toArray(new Object[0][]);
}

Performance Considerations

Large Data Sets

For large data sets, consider lazy loading or streaming approaches:

@DataProvider
public static Iterator<Object[]> largeDataSet() {
    return new Iterator<Object[]>() {
        private int current = 0;
        private final int max = 100000;
        
        @Override
        public boolean hasNext() {
            return current < max;
        }
        
        @Override
        public Object[] next() {
            return $("item" + current, current++);
        }
    };
}

Memory Optimization

Reuse common data structures:

private static final Object[][] COMMON_STRINGS = testForEach(
    "alpha", "beta", "gamma", "delta"
);

@DataProvider
public static Object[][] reusedData() {
    return COMMON_STRINGS;  // Reuse instead of recreating
}

Install with Tessl CLI

npx tessl i tessl/maven-com-tngtech-java--junit-dataprovider

docs

custom-config.md

data-formats.md

index.md

runner-annotations.md

utilities.md

tile.json