QA & Testing
API Assertion Builder
Paste any JSON API response and instantly get assertion code for Jest, Playwright, pytest, or Supertest. Choose Exact values, Type-safe, or Schema mode. 100% browser-based.
What the API Assertion Builder Generates
Manual API testing usually ends with a few console.log calls and a visual inspection of the response. That approach misses the point of automated testing: a test that checks nothing cannot tell you when the API regresses. This tool turns any JSON response body into a ready-to-use assertion block for four testing frameworks — in the mode that fits your use case.
| Assertion mode | What it checks | Best for |
|---|---|---|
| Exact values | The precise value of every field — "Alice", 25, true | Known fixture data, deterministic responses, snapshot regression |
| Type-safe | The type of every field — String, Number, Boolean | Dynamic data (user IDs, timestamps, random tokens) that changes between runs |
| Schema only | A single toMatchObject block with expected structure | Contract testing, checking shape without caring about values |
Framework Reference
Jest — Fetch or Axios
Jest is the standard test runner for Node.js and React applications. The generated assertions use expect(data.field).toBe(value) syntax and work with both fetch and axios:
it('returns valid user', async () => {
const response = await fetch('/api/users/123');
const data = await response.json();
// paste generated assertions here
expect(response.status).toBe(200);
expect(data.id).toBe("usr_01HXQR2A");
expect(data.name).toBe("Alice");
expect(data.verified).toBe(true);
});Playwright — APIRequestContext
Playwright's APIRequestContext makes HTTP requests from within a Playwright test. This lets you test the API layer and the browser UI in the same test suite, sharing authentication state between API setup calls and browser interactions:
test('API returns valid user', async ({ request }) => {
const response = await request.get('/api/users/123');
// paste generated assertions here
expect(response.status()).toBe(200);
expect(response.headers()['content-type']).toContain('application/json');
const data = await response.json();
expect(data.name).toBe("Alice");
});pytest — Requests Library
For Python backends, the requests library is the standard HTTP client for tests. The generated assertions use plain assert statements compatible with pytest's output formatting and failure messages:
import requests
def test_user_endpoint():
response = requests.get("http://localhost:8000/api/users/123")
data = response.json()
# paste generated assertions here
assert response.status_code == 200
assert "application/json" in response.headers.get("content-type", "")
assert data["name"] == "Alice"
assert isinstance(data["score"], float)Supertest — Express Integration
Supertest wraps an Express app for in-process HTTP testing — no server port needed. It pairs with Jest for assertions on the response body:
const request = require('supertest');
const app = require('../src/app');
it('returns valid user', async () => {
const response = await request(app)
.get('/api/users/123')
.expect(200)
.expect('Content-Type', /json/);
const data = response.body;
// paste generated assertions here
expect(data.name).toBe("Alice");
});RestAssured — Java / Spring Boot
RestAssured is the standard REST testing library for Java. It is widely used in Spring Boot projects alongside JUnit 5, and is the natural choice for teams that also use Selenium WebDriver for browser automation — both libraries share the same Maven/Gradle dependency chain and test runner. The generated assertions use RestAssured's fluent BDD API with Hamcrest matchers:
import io.restassured.RestAssured;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Test
void returnsValidUser() {
given()
.when()
.get("/api/users/123")
.then()
.statusCode(200)
.contentType("application/json")
.body("name", equalTo("Alice"))
.body("verified", equalTo(true))
.body("score", equalTo(4.8f))
.body("tags", hasSize(2))
.body("address.city", equalTo("Berlin"));
}Add these dependencies to your pom.xml or build.gradle to use RestAssured:
<!-- Maven -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.5.0</version>
<scope>test</scope>
</dependency>
// Gradle
testImplementation 'io.rest-assured:rest-assured:5.5.0'Assertion Depth: When to Use Each Mode
The right mode depends on what the API is returning and what you are trying to verify.
Use Exact values when testing against seeded fixture data — a user with a known ID and known fields. These assertions are the most specific and catch the most regressions, but they require the response data to be deterministic.
Use Type-safe when the response contains dynamic values — UUIDs generated at runtime, timestamps, incrementing counters, or any field whose value legitimately changes between test runs. Type assertions verify that the field exists and has the right type without breaking on different values.
Use Schema only for contract tests — tests that verify the API adheres to its documented interface without testing specific business logic. A toMatchObject schema test is stable across data changes and appropriate for integration tests between microservices.
Testing Patterns for Common Response Shapes
Paginated list responses
// Typical pagination envelope
{
"data": [{ "id": "1", "name": "Alice" }, { "id": "2", "name": "Bob" }],
"total": 42,
"page": 1,
"perPage": 20
}
// Generated assertions (Exact mode)
expect(data.total).toBe(42);
expect(data.page).toBe(1);
expect(data.data).toHaveLength(2);Error responses
// Paste the error body and set status to 400 or 422
{
"error": "Validation failed",
"details": [
{ "field": "email", "message": "must be a valid email" }
]
}
// Generated assertions
expect(response.status).toBe(422);
expect(data.error).toBe("Validation failed");
expect(data.details).toHaveLength(1);Empty responses
For endpoints that return 204 No Content or an empty body, set the status code to 204 and leave the JSON input empty. The tool will generate only the status assertion without any body checks.
Integrating with CI/CD
API tests generated with this tool can run as part of any CI pipeline. A minimal GitHub Actions workflow for Jest + Supertest:
# .github/workflows/test.yml
name: API Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm testFor Playwright API tests, the playwright/test runner handles parallel execution and retries automatically. Run with npx playwright test --project=api to target only the API test project defined in your Playwright config.
Privacy
All JSON parsing and assertion generation runs entirely in your browser. The response body you paste — which may contain personally identifiable data from development or staging environments — is never sent to any server. The tool works fully offline after the page loads.
FAQ
Common questions
What is the difference between Exact, Type-safe, and Schema modes?
Exact mode generates assertions with literal values — expect(data.name).toBe("Alice"). Use this when testing against a known fixture response. Type-safe mode generates type assertions — expect(data.name).toEqual(expect.any(String)) — useful when the response values change between test runs (user IDs, timestamps, random tokens). Schema mode generates a single toMatchObject / toMatchSchema block that validates the overall shape without checking specific values — useful for contract testing.
Why does the tool generate a flat list of assertions instead of a single toMatchObject?
Flat assertions have two advantages over a single toMatchObject: they fail with a clear message identifying exactly which field is wrong ("Expected data.user.email to be ..."), and they let you comment out individual assertions without restructuring the whole object. Schema mode gives you the toMatchObject alternative if you prefer it.
Which framework should I use for testing Express.js APIs?
Use Supertest for integration testing Express apps — it lets you import the Express app directly and make requests without starting a real HTTP server. Use Jest for unit testing individual route handlers or middleware in isolation. For end-to-end testing of a deployed API, use Playwright's APIRequestContext — it works against any HTTP endpoint and integrates with the same test runner as your browser tests.
When should I use the RestAssured output?
RestAssured is the standard HTTP/REST testing library for Java. It is commonly used in Spring Boot projects alongside JUnit 5, and by teams who also use Selenium for browser automation and want a consistent testing stack. The generated output uses REST-assured's fluent BDD API with Hamcrest matchers — given().when().get("/endpoint").then().statusCode(200).body("field", equalTo("value")). Add rest-assured and hamcrest-all to your Maven or Gradle dependencies to use it.
How does this tool handle nested objects and arrays?
Nested objects are recursively flattened up to 4 levels deep. Each leaf value gets its own assertion line — expect(data.user.address.city).toBe("Berlin"). Arrays get a length assertion (expect(data.tags).toHaveLength(2)) but individual array elements are not individually asserted, because the order and content of dynamic arrays varies. For arrays of objects, Schema mode generates an arrayContaining check that validates the structure of array elements.
Should I assert the Content-Type header?
For Playwright and Supertest, yes — header assertions catch misconfigured API servers that return HTML error pages (which parse as plain text) instead of JSON. For Jest-based tests using fetch or axios, the Content-Type assertion is optional since you are calling response.json() which will throw if the body is not JSON.
How do I use the generated assertions in a real test file?
Copy the output and paste it inside a test block. For Jest: inside it("...", async () => { const response = await fetch(...); /* paste here */ }). For Playwright: inside test("...", async ({ request }) => { const response = await request.get(...); /* paste here */ }). For pytest: inside def test_api(): response = requests.get(...) /* paste here */. For Supertest: inside it("...", async () => { /* paste here */ }).
Can I test APIs that return arrays as the root response?
Yes. If the root JSON value is an array (e.g., [{"id": 1}, {"id": 2}]), the tool generates a length assertion and — in Schema mode — an arrayContaining assertion that validates the structure of the first element. Flat mode generates assertions against index 0 to show the expected shape of each item.
Is the JSON I paste sent to a server?
No. All parsing and assertion generation runs entirely in your browser using JavaScript. The JSON body never leaves your machine. You can verify this by opening DevTools → Network while using the tool — you will see no outbound requests. The tool works offline.
More in QA & Testing