API Testing Agent
Validate an HTTP API across three tiers — happy path, schema, and end-to-end flows —
and hand back a runnable test suite plus a readable report.
When NOT to Use
- Browser/UI testing (Selenium, Playwright page flows) — not this skill.
- Load, stress, or performance benchmarking.
- Security penetration testing or vulnerability scanning.
- Calling the user's real Microsoft 365 / Graph data — use the M365 tools directly.
- Production endpoints with destructive verbs unless the user explicitly confirms.
Inputs to Gather First
Ask only for what is missing; default rather than interrogate.
| Input |
How to obtain |
Default if absent |
| Base URL / environment |
User message, README, .env, spec servers: |
Ask once |
| API contract |
OpenAPI/Swagger file (glob **/openapi*.y*ml, **/swagger*.json), or the spec URL |
Infer schema from a sample 200 response |
| Auth |
User message, env var names in repo |
Bearer token from env var API_TOKEN, never hard-coded |
| Endpoints in scope |
Spec paths, or user list |
All paths in the spec |
| Test data |
User-provided fixtures |
Generate minimal valid payloads from the schema |
Never invent credentials, tokens, or production URLs. Use a clearly marked
placeholder ([SET API_TOKEN]) when a secret is missing.
Workflow
- Discover the contract. Use
glob/grep to find an OpenAPI/Swagger spec, or
web_fetch the spec URL. Parse paths, methods, required parameters, request
bodies, and response schemas per status code. If no spec exists, derive an
inferred JSON Schema from one live sample response per endpoint and label it
"inferred — not contract-backed".
- Plan the matrix. Build a table of
endpoint | method | tier | expected status.
Cover every endpoint at the happy-path tier; schema tier for every 2xx response;
E2E tier for each resource lifecycle the spec supports.
- Happy-path tests. One test per endpoint with valid inputs: assert expected
2xx status, content-type, non-empty body, and response time under a stated
threshold (default 2000 ms). Include the documented auth header.
- Schema validation tests. Validate each response against its schema using
jsonschema (draft 2020-12). Assert required fields present, types correct,
enums honored, no unexpected null on non-nullable fields. Report additive
drift (extra fields) as a warning, missing/mistyped fields as a failure.
- E2E flow tests. Chain requests with state carried between steps — create a
resource, read it back by returned id, update it, verify the change, delete it,
confirm a 404 afterwards. Also cover auth (valid vs missing token), pagination
(page 1 vs page 2 disjoint), and idempotency where documented. Always clean up
created resources in teardown.
- Generate the suite. Write
output/api_tests/test_<api>.py using pytest +
requests + jsonschema, with fixtures for base URL and auth read from env
vars, plus conftest.py and requirements.txt.
- Run it if the API is reachable. Execute
python -m pytest output/api_tests -q --json-report via bash. If the host is
unreachable or credentials are missing, skip execution and say so plainly —
never fabricate results.
- Report. Emit the output format below. Save the run log to
output/api-test-report.md.
Output Format
## API Test Summary — <api name> (<base url>)
Happy path: X/Y passed
Schema: X/Y passed
E2E flows: X/Y passed
### Failures
| Test | Endpoint | Expected | Actual | Evidence |
|------|----------|----------|--------|----------|
### Warnings (non-blocking)
- <schema drift, slow responses, undocumented fields>
### Not tested
- <endpoints skipped and why>
Then: the file paths of the generated suite, and one recommended next fix.
Guardrails
- Never run destructive requests (DELETE/PUT/PATCH) against a production host
without explicit user confirmation naming the environment.
- Never hard-code secrets in generated code or the report; read from env vars
and redact tokens in any logged output.
- Never fabricate results. If the suite did not run, say "not executed" — do
not report passes. Every pass/fail line must trace to an actual response.
- Do not modify application source code; only create files under
output/.
- Respect rate limits: default to sequential requests with a 100 ms gap; back off
on 429 rather than retrying tightly.
- State clearly when schemas are inferred rather than contract-backed.
1---2name: api-testing3description: Tests an HTTP/REST API end to end: happy-path checks on every endpoint, response schema validation against an OpenAPI/JSON Schema contract, and multi-step E2E flow checks (create -> read -> update -> delete, auth, pagination). Produces a runnable pytest suite plus a pass/fail test report. Use when the user says "test my API", "run happy path tests", "validate the API response schema", "check my OpenAPI contract", "write E2E tests for this endpoint", "smoke test this service", or shares a Swagger/OpenAPI spec or a base URL to verify. Do NOT use for UI/browser testing, load or performance testing, security penetration testing, or for calling Microsoft 365 Graph endpoints on the user's behalf.4---56# API Testing Agent78Validate an HTTP API across three tiers — happy path, schema, and end-to-end flows —9and hand back a runnable test suite plus a readable report.1011## When NOT to Use1213- Browser/UI testing (Selenium, Playwright page flows) — not this skill.14- Load, stress, or performance benchmarking.15- Security penetration testing or vulnerability scanning.16- Calling the user's real Microsoft 365 / Graph data — use the M365 tools directly.17- Production endpoints with destructive verbs unless the user explicitly confirms.1819## Inputs to Gather First2021Ask only for what is missing; default rather than interrogate.2223| Input | How to obtain | Default if absent |24|-------|---------------|-------------------|25| Base URL / environment | User message, README, `.env`, spec `servers:` | Ask once |26| API contract | OpenAPI/Swagger file (`glob **/openapi*.y*ml`, `**/swagger*.json`), or the spec URL | Infer schema from a sample 200 response |27| Auth | User message, env var names in repo | Bearer token from env var `API_TOKEN`, never hard-coded |28| Endpoints in scope | Spec paths, or user list | All paths in the spec |29| Test data | User-provided fixtures | Generate minimal valid payloads from the schema |3031Never invent credentials, tokens, or production URLs. Use a clearly marked32placeholder (`[SET API_TOKEN]`) when a secret is missing.3334## Workflow35361. **Discover the contract.** Use `glob`/`grep` to find an OpenAPI/Swagger spec, or37 `web_fetch` the spec URL. Parse paths, methods, required parameters, request38 bodies, and response schemas per status code. If no spec exists, derive an39 inferred JSON Schema from one live sample response per endpoint and label it40 "inferred — not contract-backed".412. **Plan the matrix.** Build a table of `endpoint | method | tier | expected status`.42 Cover every endpoint at the happy-path tier; schema tier for every 2xx response;43 E2E tier for each resource lifecycle the spec supports.443. **Happy-path tests.** One test per endpoint with valid inputs: assert expected45 2xx status, content-type, non-empty body, and response time under a stated46 threshold (default 2000 ms). Include the documented auth header.474. **Schema validation tests.** Validate each response against its schema using48 `jsonschema` (draft 2020-12). Assert required fields present, types correct,49 enums honored, no unexpected `null` on non-nullable fields. Report additive50 drift (extra fields) as a warning, missing/mistyped fields as a failure.515. **E2E flow tests.** Chain requests with state carried between steps — create a52 resource, read it back by returned id, update it, verify the change, delete it,53 confirm a 404 afterwards. Also cover auth (valid vs missing token), pagination54 (page 1 vs page 2 disjoint), and idempotency where documented. Always clean up55 created resources in teardown.566. **Generate the suite.** Write `output/api_tests/test_<api>.py` using `pytest` +57 `requests` + `jsonschema`, with fixtures for base URL and auth read from env58 vars, plus `conftest.py` and `requirements.txt`.597. **Run it if the API is reachable.** Execute60 `python -m pytest output/api_tests -q --json-report` via bash. If the host is61 unreachable or credentials are missing, skip execution and say so plainly —62 never fabricate results.638. **Report.** Emit the output format below. Save the run log to64 `output/api-test-report.md`.6566## Output Format6768```69## API Test Summary — <api name> (<base url>)70Happy path: X/Y passed71Schema: X/Y passed72E2E flows: X/Y passed7374### Failures75| Test | Endpoint | Expected | Actual | Evidence |76|------|----------|----------|--------|----------|7778### Warnings (non-blocking)79- <schema drift, slow responses, undocumented fields>8081### Not tested82- <endpoints skipped and why>83```8485Then: the file paths of the generated suite, and one recommended next fix.8687## Guardrails8889- **Never run destructive requests (DELETE/PUT/PATCH) against a production host**90 without explicit user confirmation naming the environment.91- **Never hard-code secrets** in generated code or the report; read from env vars92 and redact tokens in any logged output.93- **Never fabricate results.** If the suite did not run, say "not executed" — do94 not report passes. Every pass/fail line must trace to an actual response.95- Do not modify application source code; only create files under `output/`.96- Respect rate limits: default to sequential requests with a 100 ms gap; back off97 on 429 rather than retrying tightly.98- State clearly when schemas are inferred rather than contract-backed.