API Test Script Builder
Generate complete, runnable API test scripts from any input in your preferred framework.
Supported Input Types
- Plain English — "Test a login endpoint that takes email and password and returns a token"
- Curl commands —
curl -X POST https://api.example.com/login -d '{"email":"..."}'
- Swagger / OpenAPI — Paste YAML or JSON spec
- Postman Collection — Paste exported JSON
- GraphQL — Query + schema + expected response shape
- Endpoint table — Method + URL + body + expected response
Supported Output Frameworks
| Framework |
Best For |
Output File |
| Python pytest |
CI/CD pipelines, backend QA |
test_api.py + .env.example |
| Postman Collection |
Manual + automated testing, team sharing |
collection.json |
| JavaScript Jest |
Frontend / Node.js teams |
api.test.js + .env.example |
Default: Python pytest — most portable, works in any CI/CD pipeline.
Workflow
Step 1 — Parse the Input
Extract for each endpoint:
- HTTP method (GET, POST, PUT, PATCH, DELETE)
- URL / path (note path params like
{id})
- Request headers (Content-Type, auth headers)
- Request body / query params with data types
- Expected response: status code + response body shape
- Auth type: Bearer token | API key (header or query) | Basic auth | OAuth2 | None
If details are missing, make sensible assumptions and document them as comments in the code.
Step 2 — Identify What to Test Per Endpoint
| Test Type |
Description |
| ✅ Happy Path |
Valid request → expected 2xx + correct response shape |
| ❌ Invalid Input |
Missing/wrong fields → 400/422 |
| 🔐 Unauthorized |
No/invalid/expired token → 401 |
| 🚫 Forbidden |
Valid token, insufficient permissions → 403 |
| 🔍 Not Found |
Non-existent ID or resource → 404 |
| 🔲 Boundary |
Empty string, null, very long values, special characters |
| 📋 Schema Check |
Response fields exist and have correct types |
Step 3 — Generate the Script
Python pytest (test_api.py + .env.example)
Key rules:
BASE_URL and AUTH_TOKEN read from environment variables — never hardcoded in tests
- One class per endpoint group
- Use
pytest.fixture for shared setup (headers, auth token)
- Use
response.json() only after asserting status_code — avoids misleading errors
- Mark expected-failure tests with
@pytest.mark.xfail where appropriate
- For endpoints with path params, parametrize with
@pytest.mark.parametrize
Structure:
"""
API Tests: <Service Name>
Base URL: <base_url>
Setup:
pip install pytest requests python-dotenv
cp .env.example .env # fill in your values
Run: pytest test_api.py -v
"""
import os
import pytest
import requests
from dotenv import load_dotenv
load_dotenv()
BASE_URL = os.getenv("BASE_URL", "https://api.example.com")
AUTH_TOKEN = os.getenv("AUTH_TOKEN", "")
HEADERS = {"Content-Type": "application/json", "Authorization": f"Bearer {AUTH_TOKEN}"}
class TestLoginEndpoint:
"""POST /auth/login"""
def test_login_success(self):
payload = {"email": "test@example.com", "password": "ValidPass123"}
r = requests.post(f"{BASE_URL}/auth/login", json=payload)
assert r.status_code == 200
data = r.json()
assert "token" in data
assert isinstance(data["token"], str)
assert len(data["token"]) > 0
def test_login_wrong_password(self):
r = requests.post(f"{BASE_URL}/auth/login",
json={"email": "test@example.com", "password": "wrong"})
assert r.status_code == 401
def test_login_missing_email(self):
r = requests.post(f"{BASE_URL}/auth/login", json={"password": "ValidPass123"})
assert r.status_code in [400, 422]
def test_login_empty_body(self):
r = requests.post(f"{BASE_URL}/auth/login", json={})
assert r.status_code in [400, 422]
def test_login_invalid_email_format(self):
r = requests.post(f"{BASE_URL}/auth/login",
json={"email": "notanemail", "password": "ValidPass123"})
assert r.status_code in [400, 422]
def test_login_no_auth_header(self):
# Endpoint itself doesn't require auth, but confirms endpoint is reachable
r = requests.post(f"{BASE_URL}/auth/login", json={})
assert r.status_code != 500 # Should never return a server error
.env.example:
BASE_URL=https://api.example.com
AUTH_TOKEN=your-token-here
Postman Collection (collection.json)
Generate valid Postman Collection v2.1 JSON with:
- Collection name + description
- One folder per endpoint group
- Each request: name, method, URL with path variables, headers, raw JSON body
Tests tab with pm.test(...) assertions for status code + response fields
- Pre-request script for auth token refresh if OAuth2
- Environment variables:
{{base_url}}, {{auth_token}} — never hardcoded URLs
JavaScript Jest (api.test.js + .env.example)
Key rules:
- Use
axios with try/catch — axios throws on 4xx/5xx, so catch and assert error.response.status
- Read config from
process.env via dotenv
- One
describe block per endpoint
beforeAll for any auth setup (e.g. login to get token)
Structure:
/**
* API Tests: <Service Name>
* Setup: npm install jest axios dotenv
* Run: npx jest api.test.js --verbose
*/
require('dotenv').config();
const axios = require('axios');
const BASE_URL = process.env.BASE_URL || 'https://api.example.com';
const AUTH_TOKEN = process.env.AUTH_TOKEN || '';
const headers = { Authorization: `Bearer ${AUTH_TOKEN}`, 'Content-Type': 'application/json' };
describe('POST /auth/login', () => {
test('200 + token for valid credentials', async () => {
const res = await axios.post(`${BASE_URL}/auth/login`,
{ email: 'test@example.com', password: 'ValidPass123' });
expect(res.status).toBe(200);
expect(res.data).toHaveProperty('token');
expect(typeof res.data.token).toBe('string');
});
test('401 for wrong password', async () => {
await expect(
axios.post(`${BASE_URL}/auth/login`, { email: 'test@example.com', password: 'wrong' })
).rejects.toMatchObject({ response: { status: 401 } });
});
test('400/422 for missing fields', async () => {
await expect(
axios.post(`${BASE_URL}/auth/login`, {})
).rejects.toSatisfy(e => [400, 422].includes(e.response?.status));
});
});
Step 4 — Save & Present
- Save all output files to
/mnt/user-data/outputs/
- Use
present_files to deliver
- Print a chat summary containing:
- List of endpoints covered
- Total test count (broken down by test type: happy path / negative / boundary)
- Framework used
- How to install dependencies and run
- Any assumptions made (e.g. inferred auth type, guessed base URL)
Auth Handling Reference
| Auth Type |
How to implement |
| Bearer token |
Authorization: Bearer {{token}} header |
| API key (header) |
X-API-Key: {{api_key}} header |
| API key (query) |
?api_key={{api_key}} appended to URL |
| Basic auth |
Authorization: Basic base64(user:pass) |
| OAuth2 |
beforeAll login call → store token → inject into all requests |
| No auth |
Confirm 401 is returned when auth header is added unexpectedly |
Tips for Best Results
- Share the full spec if you have Swagger/OpenAPI — it gives the most complete coverage automatically.
- Mention the auth type — otherwise Bearer token is assumed.
- Specify the framework if you have a preference — otherwise Python pytest is generated.
- Multiple endpoints? List or paste them all — each gets its own class/describe block.
- Have a Postman collection already? Share it to generate pytest or Jest equivalents.
- GraphQL? Share the query + expected response shape — test coverage includes variable injection and error states.
1---2name: api-test-script-builder3description: Generates complete, ready-to-run API test scripts from any input — endpoint descriptions, Swagger/OpenAPI specs, Postman collections, curl commands, or plain English. Outputs working test code in the user's preferred framework: Python pytest + requests, Postman Collection (JSON), or JavaScript Jest + axios. Always trigger this skill for ANY of these situations: "API testing", "test this endpoint", "write API tests", "generate test cases", "Postman collection", "pytest for API", "REST API test", "API automation", "validate API response", "check my endpoint", "test my routes", "QA this API", sharing a Swagger/OpenAPI spec, sharing a curl command, sharing an API route or payload, or any request involving HTTP endpoint verification. Trigger even for vague inputs like "test this" when an API context is present — structured, runnable scripts are always better than ad-hoc manual testing.4---56# API Test Script Builder78Generate complete, runnable API test scripts from any input in your preferred framework.910---1112## Supported Input Types1314- **Plain English** — "Test a login endpoint that takes email and password and returns a token"15- **Curl commands** — `curl -X POST https://api.example.com/login -d '{"email":"..."}'`16- **Swagger / OpenAPI** — Paste YAML or JSON spec17- **Postman Collection** — Paste exported JSON18- **GraphQL** — Query + schema + expected response shape19- **Endpoint table** — Method + URL + body + expected response2021---2223## Supported Output Frameworks2425| Framework | Best For | Output File |26|---|---|---|27| **Python pytest** | CI/CD pipelines, backend QA | `test_api.py` + `.env.example` |28| **Postman Collection** | Manual + automated testing, team sharing | `collection.json` |29| **JavaScript Jest** | Frontend / Node.js teams | `api.test.js` + `.env.example` |3031**Default: Python pytest** — most portable, works in any CI/CD pipeline.3233---3435## Workflow3637### Step 1 — Parse the Input3839Extract for each endpoint:40- HTTP method (GET, POST, PUT, PATCH, DELETE)41- URL / path (note path params like `{id}`)42- Request headers (Content-Type, auth headers)43- Request body / query params with data types44- Expected response: status code + response body shape45- Auth type: Bearer token | API key (header or query) | Basic auth | OAuth2 | None4647If details are missing, make sensible assumptions and document them as comments in the code.4849---5051### Step 2 — Identify What to Test Per Endpoint5253| Test Type | Description |54|---|---|55| ✅ Happy Path | Valid request → expected 2xx + correct response shape |56| ❌ Invalid Input | Missing/wrong fields → 400/422 |57| 🔐 Unauthorized | No/invalid/expired token → 401 |58| 🚫 Forbidden | Valid token, insufficient permissions → 403 |59| 🔍 Not Found | Non-existent ID or resource → 404 |60| 🔲 Boundary | Empty string, null, very long values, special characters |61| 📋 Schema Check | Response fields exist and have correct types |6263---6465### Step 3 — Generate the Script6667#### Python pytest (`test_api.py` + `.env.example`)6869Key rules:70- `BASE_URL` and `AUTH_TOKEN` read from environment variables — never hardcoded in tests71- One class per endpoint group72- Use `pytest.fixture` for shared setup (headers, auth token)73- Use `response.json()` only after asserting `status_code` — avoids misleading errors74- Mark expected-failure tests with `@pytest.mark.xfail` where appropriate75- For endpoints with path params, parametrize with `@pytest.mark.parametrize`7677Structure:78```79"""80API Tests: <Service Name>81Base URL: <base_url>8283Setup:84 pip install pytest requests python-dotenv85 cp .env.example .env # fill in your values86 Run: pytest test_api.py -v87"""8889import os90import pytest91import requests92from dotenv import load_dotenv9394load_dotenv()9596BASE_URL = os.getenv("BASE_URL", "https://api.example.com")97AUTH_TOKEN = os.getenv("AUTH_TOKEN", "")98HEADERS = {"Content-Type": "application/json", "Authorization": f"Bearer {AUTH_TOKEN}"}99100101class TestLoginEndpoint:102 """POST /auth/login"""103104 def test_login_success(self):105 payload = {"email": "test@example.com", "password": "ValidPass123"}106 r = requests.post(f"{BASE_URL}/auth/login", json=payload)107 assert r.status_code == 200108 data = r.json()109 assert "token" in data110 assert isinstance(data["token"], str)111 assert len(data["token"]) > 0112113 def test_login_wrong_password(self):114 r = requests.post(f"{BASE_URL}/auth/login",115 json={"email": "test@example.com", "password": "wrong"})116 assert r.status_code == 401117118 def test_login_missing_email(self):119 r = requests.post(f"{BASE_URL}/auth/login", json={"password": "ValidPass123"})120 assert r.status_code in [400, 422]121122 def test_login_empty_body(self):123 r = requests.post(f"{BASE_URL}/auth/login", json={})124 assert r.status_code in [400, 422]125126 def test_login_invalid_email_format(self):127 r = requests.post(f"{BASE_URL}/auth/login",128 json={"email": "notanemail", "password": "ValidPass123"})129 assert r.status_code in [400, 422]130131 def test_login_no_auth_header(self):132 # Endpoint itself doesn't require auth, but confirms endpoint is reachable133 r = requests.post(f"{BASE_URL}/auth/login", json={})134 assert r.status_code != 500 # Should never return a server error135```136137`.env.example`:138```139BASE_URL=https://api.example.com140AUTH_TOKEN=your-token-here141```142143---144145#### Postman Collection (`collection.json`)146147Generate valid Postman Collection v2.1 JSON with:148- Collection name + description149- One folder per endpoint group150- Each request: name, method, URL with path variables, headers, raw JSON body151- `Tests` tab with `pm.test(...)` assertions for status code + response fields152- Pre-request script for auth token refresh if OAuth2153- Environment variables: `{{base_url}}`, `{{auth_token}}` — never hardcoded URLs154155---156157#### JavaScript Jest (`api.test.js` + `.env.example`)158159Key rules:160- Use `axios` with try/catch — axios throws on 4xx/5xx, so catch and assert `error.response.status`161- Read config from `process.env` via `dotenv`162- One `describe` block per endpoint163- `beforeAll` for any auth setup (e.g. login to get token)164165Structure:166```javascript167/**168 * API Tests: <Service Name>169 * Setup: npm install jest axios dotenv170 * Run: npx jest api.test.js --verbose171 */172173require('dotenv').config();174const axios = require('axios');175176const BASE_URL = process.env.BASE_URL || 'https://api.example.com';177const AUTH_TOKEN = process.env.AUTH_TOKEN || '';178const headers = { Authorization: `Bearer ${AUTH_TOKEN}`, 'Content-Type': 'application/json' };179180describe('POST /auth/login', () => {181 test('200 + token for valid credentials', async () => {182 const res = await axios.post(`${BASE_URL}/auth/login`,183 { email: 'test@example.com', password: 'ValidPass123' });184 expect(res.status).toBe(200);185 expect(res.data).toHaveProperty('token');186 expect(typeof res.data.token).toBe('string');187 });188189 test('401 for wrong password', async () => {190 await expect(191 axios.post(`${BASE_URL}/auth/login`, { email: 'test@example.com', password: 'wrong' })192 ).rejects.toMatchObject({ response: { status: 401 } });193 });194195 test('400/422 for missing fields', async () => {196 await expect(197 axios.post(`${BASE_URL}/auth/login`, {})198 ).rejects.toSatisfy(e => [400, 422].includes(e.response?.status));199 });200});201```202203---204205### Step 4 — Save & Present2062071. Save all output files to `/mnt/user-data/outputs/`2082. Use `present_files` to deliver2093. Print a chat summary containing:210 - List of endpoints covered211 - Total test count (broken down by test type: happy path / negative / boundary)212 - Framework used213 - How to install dependencies and run214 - Any assumptions made (e.g. inferred auth type, guessed base URL)215216---217218## Auth Handling Reference219220| Auth Type | How to implement |221|---|---|222| Bearer token | `Authorization: Bearer {{token}}` header |223| API key (header) | `X-API-Key: {{api_key}}` header |224| API key (query) | `?api_key={{api_key}}` appended to URL |225| Basic auth | `Authorization: Basic base64(user:pass)` |226| OAuth2 | `beforeAll` login call → store token → inject into all requests |227| No auth | Confirm 401 is returned when auth header is added unexpectedly |228229---230231## Tips for Best Results232233- **Share the full spec** if you have Swagger/OpenAPI — it gives the most complete coverage automatically.234- **Mention the auth type** — otherwise Bearer token is assumed.235- **Specify the framework** if you have a preference — otherwise Python pytest is generated.236- **Multiple endpoints?** List or paste them all — each gets its own class/describe block.237- **Have a Postman collection already?** Share it to generate pytest or Jest equivalents.238- **GraphQL?** Share the query + expected response shape — test coverage includes variable injection and error states.