Skip to main content

API Testing

Selenium Boot supports pure API tests and hybrid UI + API tests out of the box — same framework, same config, same report.


Pure API Tests — BaseApiTest

Extend BaseApiTest instead of BaseTest. No browser is launched; the full framework lifecycle still applies (reporting, @TestData, retry, CI gates).

import com.seleniumboot.test.BaseApiTest;
import com.seleniumboot.client.ApiClient;
import com.seleniumboot.client.ApiResponse;
import org.testng.annotations.Test;

public class UserApiTest extends BaseApiTest {

@Test
public void getUserById() {
ApiResponse res = ApiClient.get("https://api.example.com/users/1")
.send();

res.assertStatus(200);
res.assertJson("$.name", "John Doe");
}
}

ApiClient — Fluent HTTP Client

Supported methods

ApiClient.get("/api/users")
ApiClient.post("/api/users")
ApiClient.put("/api/users/1")
ApiClient.patch("/api/users/1")
ApiClient.delete("/api/users/1")

Base URL

By default, ApiClient uses api.baseUrl from selenium-boot.yml. Falls back to execution.baseUrl if not set.

api:
baseUrl: https://api.example.com
timeoutSeconds: 30
logBody: false # set true to log request/response body in step timeline

Override per-request with ApiClient.to(url):

ApiClient.to("https://other-service.com").get("/health").send();

Request headers and body

ApiClient.post("/api/users")
.header("X-Request-ID", "abc123")
.contentType("application/json")
.body(Map.of("name", "Alice", "email", "alice@example.com"))
.send();

ApiResponse — Assertions and Extraction

Status assertion

res.assertStatus(201);

Body assertions

res.assertBodyContains("success");
res.assertJson("$.user.name", "Alice");

JSONPath extraction

String token = res.json("$.token");
int id = res.json("$.user.id", Integer.class);

Deserialize to object

User user = res.asObject(User.class);

Schema validation

Validate the response structure against a JSON Schema file:

res.assertStatus(200).assertSchema("schemas/user.json");

Place schema files under src/test/resources/schemas/. See Schema Validation below.

Raw access

int    status   = res.status();
String body = res.body();
long duration = res.durationMs();

Fluent chaining

ApiClient.get("/api/users/1")
.send()
.assertStatus(200)
.assertJson("$.name", "Alice")
.assertSchema("schemas/user.json");

Schema Validation

Validate that a response matches a JSON Schema (Draft-07):

src/test/resources/schemas/user.json

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["id", "name", "email"],
"properties": {
"id": { "type": "integer" },
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string" }
}
}
ApiClient.get("/api/users/1")
.send()
.assertStatus(200)
.assertSchema("schemas/user.json");

Requires com.networknt:json-schema-validator in your pom.xml:

<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.4.3</version>
</dependency>

Hybrid UI + API Tests

Mix API calls and browser interactions in the same test. Available in BaseTest via apiClient():

public class CheckoutTest extends BaseTest {

@Test
public void placeOrder() {
// Set up order via API (fast)
ApiResponse order = apiClient().post("/api/orders")
.body(Map.of("productId", 42, "qty", 1))
.send()
.assertStatus(201);

String orderId = order.json("$.orderId");

// Verify in the UI
open("/orders/" + orderId);
Assert.assertEquals(getText(By.id("status")), "Pending");
}
}

Step Timeline

Every ApiClient request is automatically logged in the step timeline:

[API] GET /api/users/1 → 200 (143ms)
[API] POST /api/orders → 201 (89ms)
[API] DELETE /api/orders/5 → 404 (12ms) ← logged as FAIL

Enable body logging in selenium-boot.yml:

api:
logBody: true