</>

Technology

API Automation

Difficulty

Advanced

Interview Question

How would you design an API test automation framework from scratch for a team?

Answer

Scenario: Designing an API Test Automation Framework

Framework Architecture

CODE
api-test-framework/
├── src/
│   ├── main/java/
│   │   ├── config/
│   │   │   └── ConfigManager.java       ← Read config.properties
│   │   ├── api/
│   │   │   ├── BaseApi.java             ← Base RequestSpec setup
│   │   │   ├── UserApi.java             ← User endpoint methods
│   │   │   ├── AuthApi.java             ← Auth endpoint methods
│   │   │   └── OrderApi.java            ← Order endpoint methods
│   │   ├── models/
│   │   │   ├── User.java                ← POJO for User
│   │   │   └── Order.java               ← POJO for Order
│   │   └── utils/
│   │       ├── TestDataFactory.java     ← Generate test data
│   │       └── FileUtils.java           ← File helpers
│   └── test/java/
│       ├── tests/
│       │   ├── UserApiTest.java
│       │   ├── AuthApiTest.java
│       │   └── OrderApiTest.java
│       └── schemas/
│           └── user-schema.json         ← JSON schema files
├── src/test/resources/
│   ├── config.properties
│   └── testdata/
│       └── users.csv
├── pom.xml
└── testng.xml

Base API Class

Java
public class BaseApi {

    private static String BASE_URL;
    private static String AUTH_TOKEN;

    @BeforeSuite
    public void setUp() {
        BASE_URL = ConfigManager.get("base.url");
        AUTH_TOKEN = AuthApi.getToken();

        RestAssured.baseURI = BASE_URL;
        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
    }

    protected RequestSpecification getAuthSpec() {
        return given()
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + AUTH_TOKEN);
    }

    protected RequestSpecification getPublicSpec() {
        return given()
                    .header("Content-Type", "application/json");
    }
}

API Layer — UserApi

Java
public class UserApi extends BaseApi {

    public Response createUser(User user) {
        return getAuthSpec()
                    .body(user)
                    .when()
                    .post("/api/users");
    }

    public Response getUserById(int userId) {
        return getAuthSpec()
                    .pathParam("id", userId)
                    .when()
                    .get("/api/users/{id}");
    }

    public Response updateUser(int userId, User user) {
        return getAuthSpec()
                    .pathParam("id", userId)
                    .body(user)
                    .when()
                    .put("/api/users/{id}");
    }

    public Response deleteUser(int userId) {
        return getAuthSpec()
                    .pathParam("id", userId)
                    .when()
                    .delete("/api/users/{id}");
    }
}

Test Class — Clean and Readable

Java
public class UserApiTest extends BaseApi {

    private UserApi userApi = new UserApi();
    private static int createdUserId;

    @Test(priority = 1)
    public void testCreateUser() {
        User user = TestDataFactory.createRandomUser();

        Response response = userApi.createUser(user);

        assertEquals(response.getStatusCode(), 201);
        assertNotNull(response.jsonPath().getInt("id"));
        assertEquals(response.jsonPath().getString("name"), user.getName());

        createdUserId = response.jsonPath().getInt("id");
    }

    @Test(priority = 2, dependsOnMethods = "testCreateUser")
    public void testGetCreatedUser() {
        Response response = userApi.getUserById(createdUserId);

        assertEquals(response.getStatusCode(), 200);
        assertEquals(response.jsonPath().getInt("id"), createdUserId);
    }

    @Test(priority = 3, dependsOnMethods = "testGetCreatedUser")
    public void testDeleteUser() {
        Response response = userApi.deleteUser(createdUserId);
        assertEquals(response.getStatusCode(), 204);
    }
}

Configuration Management

PROPERTIES
# config.properties
base.url=https://api.example.com
test.username=testuser
test.password=testpass
Java
public class ConfigManager {
    private static Properties props = new Properties();

    static {
        props.load(new FileInputStream("src/test/resources/config.properties"));
    }

    public static String get(String key) {
        return props.getProperty(key);
    }
}

CI/CD Integration

YAML
# pom.xml profile for CI
<profiles>
  <profile>
    <id>staging</id>
    <properties>
      <base.url>https://api.staging.com</base.url>
    </properties>
  </profile>
</profiles>
Bash
# Run staging tests
mvn test -P staging -Dgroups="smoke"

Follow AutomateQA

Related Topics