</>

Technology

API Automation

Difficulty

Intermediate

Interview Question

How do you implement data-driven API testing with Rest Assured and TestNG?

Answer

Data-Driven API Testing with Rest Assured + TestNG

Data-driven testing runs the same test logic with multiple sets of data, maximizing test coverage with minimal code.

Method 1: @DataProvider with Inline Data

Java
public class DataDrivenUserTest {

    @DataProvider(name = "createUserData")
    public Object[][] createUserData() {
        return new Object[][] {
            // name,          email,                  status,   expectedCode
            { "John Doe",    "john@example.com",     "active", 201 },
            { "Jane Smith",  "jane@example.com",     "active", 201 },
            { "",            "invalid",               "active", 400 }, // empty name
            { "Alice",       "not-an-email",          "active", 400 }, // bad email
            { "Bob",         "bob@example.com",      "invalid", 400 }  // bad status
        };
    }

    @Test(dataProvider = "createUserData")
    public void testCreateUser(String name, String email, String status, int expectedCode) {
        String body = String.format(
            "{ \"name\": \"%s\", \"email\": \"%s\", \"status\": \"%s\" }",
            name, email, status
        );

        given()
            .contentType(ContentType.JSON)
            .body(body)
            .when()
            .post("/api/users")
            .then()
            .statusCode(expectedCode);
    }
}

Method 2: @DataProvider from CSV File

Java
@DataProvider(name = "csvUserData")
public Object[][] csvUserData() throws IOException {
    List<Object[]> data = new ArrayList<>();

    try (CSVReader reader = new CSVReader(
            new FileReader("src/test/resources/testdata/users.csv"))) {

        String[] row;
        reader.readNext(); // skip header

        while ((row = reader.readNext()) != null) {
            data.add(new Object[]{ row[0], row[1], Integer.parseInt(row[2]) });
        }
    }

    return data.toArray(new Object[0][]);
}

// users.csv:
// name,email,expectedStatus
// John,john@test.com,201
// ,invalid,400

Method 3: @DataProvider from JSON File

Java
// testdata/users.json
// [
//   { "name": "Alice", "email": "alice@test.com", "expected": 201 },
//   { "name": "",      "email": "bad",             "expected": 400 }
// ]

@DataProvider(name = "jsonUserData")
public Object[][] jsonUserData() throws IOException {
    String content = new String(Files.readAllBytes(
        Paths.get("src/test/resources/testdata/users.json")));

    JSONArray jsonArray = new JSONArray(content);
    Object[][] data = new Object[jsonArray.length()][3];

    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject obj = jsonArray.getJSONObject(i);
        data[i][0] = obj.getString("name");
        data[i][1] = obj.getString("email");
        data[i][2] = obj.getInt("expected");
    }

    return data;
}

Method 4: Parallel Data-Driven Tests

Java
@DataProvider(name = "parallelData", parallel = true)
public Object[][] parallelData() {
    return new Object[][] {
        { "user1@test.com", 200 },
        { "user2@test.com", 200 },
        { "user3@test.com", 200 }
    };
}

@Test(dataProvider = "parallelData")
public void testGetUserByEmail(String email, int expectedCode) {
    given()
        .queryParam("email", email)
        .when()
        .get("/api/users/search")
        .then()
        .statusCode(expectedCode);
}

testng.xml Configuration for Data-Driven

XML
<suite name="API Data-Driven Tests" parallel="tests" thread-count="4">
    <test name="User API Tests">
        <classes>
            <class name="tests.DataDrivenUserTest"/>
        </classes>
    </test>
</suite>

Test Results View

Running with 5 data sets shows 5 separate results:

CODE
testCreateUser[0] - PASS (John Doe → 201)
testCreateUser[1] - PASS (Jane Smith → 201)
testCreateUser[2] - PASS (empty name → 400)
testCreateUser[3] - PASS (bad email → 400)
testCreateUser[4] - PASS (bad status → 400)

Follow AutomateQA

Related Topics