Test Script Examples
Copy-paste patterns for the most common API testing scenarios. Each example is self-contained and ready to drop into the Test Script editor of any request.
Checking Status Codes
Expect exactly 200
fc.test("Returns 200 OK", function () {
fc.response.to.have.status(200);
});
Expect one of several success codes
Useful for POST endpoints that return 200 or 201 depending on whether the resource was created or already existed:
fc.test("Request succeeded", function () {
fc.expect(fc.response.code).to.be.oneOf([200, 201]);
});
Expect any 2xx status
fc.test("Response is a success", function () {
fc.response.to.be.ok;
});
Expect a specific error
When deliberately testing that an invalid request is rejected:
fc.test("Missing fields returns 400", function () {
fc.response.to.have.status(400);
});
Checking the Response Body
Check that a field exists
fc.test("Response has an id", function () {
var body = fc.response.json();
fc.expect(body.id).to.exist;
});
Check a field value
fc.test("User is active", function () {
var body = fc.response.json();
fc.expect(body.status).to.equal("active");
});
Check a nested field
fc.test("Billing address has a country", function () {
var body = fc.response.json();
fc.expect(body.billing.address.country).to.exist;
});
Check a field is a number above zero
fc.test("Price is positive", function () {
var body = fc.response.json();
fc.expect(body.price).to.be.a("number");
fc.expect(body.price).to.be.above(0);
});
Check an array is not empty
fc.test("Results list is not empty", function () {
var body = fc.response.json();
fc.expect(body.results).to.be.an("array");
fc.expect(body.results).to.have.lengthOf.at.least(1);
});
Check that a value is one of a known set
fc.test("Role is valid", function () {
var body = fc.response.json();
fc.expect(body.role).to.be.oneOf(["admin", "editor", "viewer"]);
});
Check the body contains a specific string
fc.test("Success message is present", function () {
fc.expect(fc.response.text()).to.include("successfully created");
});
JSON Schema Validation
Use this to catch structural changes — renamed fields, wrong types, missing required fields — without writing individual assertions for each property.
Validate a user object
fc.test("User object matches expected schema", function () {
fc.response.to.have.jsonSchema({
type: "object",
required: ["id", "name", "email"],
properties: {
id: { type: "integer" },
name: { type: "string", minLength: 1 },
email: { type: "string", format: "email" },
createdAt: { type: "string" }
}
});
});
Validate a list response
fc.test("Paginated response matches schema", function () {
fc.response.to.have.jsonSchema({
type: "object",
required: ["data", "total", "page"],
properties: {
data: { type: "array" },
total: { type: "integer", minimum: 0 },
page: { type: "integer", minimum: 1 }
}
});
});
Checking Headers
Check a header is present
fc.test("Has content type header", function () {
fc.response.to.have.header("content-type");
});
Check a header value
fc.test("Content type is JSON", function () {
var contentType = fc.response.headers.get("content-type");
fc.expect(contentType).to.include("application/json");
});
Check rate limit headers
fc.test("Rate limit headers are present", function () {
fc.response.to.have.header("x-ratelimit-limit");
fc.response.to.have.header("x-ratelimit-remaining");
});
fc.test("Rate limit not exceeded", function () {
var remaining = parseInt(fc.response.headers.get("x-ratelimit-remaining"));
fc.expect(remaining).to.be.above(0);
});
Response Timing
Ensure a fast response
fc.test("Responds in under 500ms", function () {
fc.expect(fc.response.responseTime).to.be.below(500);
});
Warn on slow response (soft limit)
fc.test("Response time is acceptable", function () {
fc.expect(fc.response.responseTime).to.be.below(2000);
});
Authentication Flows — Chaining Requests
The most common use of test scripts: extract a token from a login response and store it so subsequent requests can use it.
Login and store access token
Put this on your login or token endpoint:
fc.test("Login succeeded", function () {
fc.expect(fc.response.code).to.equal(200);
});
fc.test("Access token is present", function () {
var body = fc.response.json();
fc.expect(body.access_token).to.exist;
fc.expect(body.access_token).to.be.a("string");
fc.expect(body.access_token.length).to.be.above(0);
// Store it — all subsequent requests in this run can use {{authToken}}
fc.environment.set("authToken", body.access_token);
});
Then add Authorization: Bearer {{authToken}} to the headers of every subsequent request. The Collection Runner substitutes the value automatically.
Login and store both access and refresh token
fc.test("Tokens are present", function () {
var body = fc.response.json();
fc.expect(body.access_token).to.exist;
fc.expect(body.refresh_token).to.exist;
fc.environment.set("authToken", body.access_token);
fc.environment.set("refreshToken", body.refresh_token);
});
Store a created resource's ID for later requests
Put this on a POST /resources endpoint:
fc.test("Resource was created", function () {
fc.expect(fc.response.code).to.equal(201);
});
fc.test("Store new resource ID", function () {
var id = fc.response.json().id;
fc.expect(id).to.exist;
fc.environment.set("resourceId", id.toString());
});
Use {{resourceId}} in the URL of subsequent GET, PUT, and DELETE requests:
GET https://api.example.com/resources/{{resourceId}}
CRUD Sequence
A full create-read-update-delete sequence. Each script stores the result so the next request can use it.
POST /users — Create:
fc.test("User created", function () {
fc.expect(fc.response.code).to.equal(201);
var body = fc.response.json();
fc.expect(body.id).to.exist;
fc.environment.set("userId", body.id.toString());
});
GET /users/ — Read:
fc.test("User found", function () {
fc.response.to.have.status(200);
var body = fc.response.json();
fc.expect(body.id.toString()).to.equal(fc.environment.get("userId"));
});
PUT /users/ — Update:
fc.test("User updated", function () {
fc.response.to.have.status(200);
var body = fc.response.json();
fc.expect(body.name).to.equal("Updated Name");
});
DELETE /users/ — Delete:
fc.test("User deleted", function () {
fc.expect(fc.response.code).to.be.oneOf([200, 204]);
});
Error Handling Scenarios
Validate that a 400 includes an error message
fc.test("Error response has a message", function () {
fc.expect(fc.response.code).to.equal(400);
var body = fc.response.json();
fc.expect(body.message).to.exist;
fc.expect(body.message).to.be.a("string");
});
Validate specific validation errors
fc.test("Validation errors list specific fields", function () {
var body = fc.response.json();
fc.expect(body.errors).to.be.an("array");
var fields = body.errors.map(function(e) { return e.field; });
fc.expect(fields).to.include("email");
});
Expect 401 when no token is provided
fc.test("Returns 401 without auth", function () {
fc.response.to.be.unauthorized;
});
fc.test("Error body has a message", function () {
var body = fc.response.json();
fc.expect(body.message).to.include("Unauthorized");
});
Pagination
Check a paginated list response
fc.test("Returns a page of results", function () {
var body = fc.response.json();
fc.expect(body.data).to.be.an("array");
fc.expect(body.data.length).to.be.at.most(20); // max page size
fc.expect(body.page).to.be.a("number");
fc.expect(body.total).to.be.a("number");
});
Store the next page cursor
fc.test("Cursor is present for next page", function () {
var body = fc.response.json();
if (body.nextCursor) {
fc.environment.set("nextCursor", body.nextCursor);
}
});
Conditional Skipping and Flow Control
Stop the run if a critical step fails
If a login request fails, there is no point running the rest of the collection — all subsequent requests will fail with 401 anyway:
fc.test("Login succeeded", function () {
if (fc.response.code !== 200) {
fc.execution.abort();
}
fc.expect(fc.response.code).to.equal(200);
});
Skip cleanup if setup failed
var created = fc.environment.get("resourceId");
if (!created) {
fc.execution.setNextRequest("End of Suite"); // jump past cleanup
}
Debugging a Failing Test
When a test is failing and you cannot see why, log the response to the Console:
console.log("Status:", fc.response.code);
console.log("Body:", fc.response.text());
var body = fc.response.json();
console.log("Parsed:", JSON.stringify(body, null, 2));
Open the Console panel (`Cmd/Ctrl + ``) to see the output. In the Collection Runner, these logs appear in the detail panel for each result row.