Agent skill
api-testing
Tool-based API testing with Postman and Bruno - collections, environments, test assertions, CI integration. Use when: postman, bruno, API testing, test API endpoint, API collection, HTTP request testing, endpoint validation.
Install this agent skill to your Project
npx add-skill https://github.com/ScientiaCapital/skills/tree/main/active/api-testing-skill
SKILL.md
This skill complements testing-skill (code-based tests) and api-design-skill (API structure). Use this when you need to test existing APIs with dedicated tools rather than writing programmatic tests.
Key distinction:
- testing-skill: Code-based tests (supertest, MSW, pytest requests)
- api-testing-skill: Tool-based tests (Postman, Bruno collections)
- api-design-skill: How to design APIs (structure, conventions)
<quick_start> Postman Quick Test:
// Tests tab in Postman
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response has user data", function () {
const json = pm.response.json();
pm.expect(json).to.have.property("id");
pm.expect(json).to.have.property("email");
});
Bruno Quick Test:
// tests/get-user.bru
meta {
name: Get User
type: http
seq: 1
}
get {
url: {{baseUrl}}/api/users/{{userId}}
}
tests {
test("should return 200", function() {
expect(res.status).to.equal(200);
});
}
Environment Setup:
{
"baseUrl": "https://api.example.com",
"apiKey": "test_key_xxx"
}
</quick_start>
<success_criteria> API testing is successful when:
- All endpoints have at least one happy path test
- Error cases tested (4xx, 5xx responses)
- Response schema validated (not just status codes)
- Environment variables used for all configurable values
- Collections organized by resource/domain
- Authentication flows tested end-to-end
- CI pipeline runs collections on every PR
- Test data is reproducible (fixtures or dynamic generation) </success_criteria>
<tool_comparison>
Postman vs Bruno
| Feature | Postman | Bruno |
|---|---|---|
| Storage | Cloud/Local | Git-native (.bru files) |
| Collaboration | Team sync | Git branches |
| Pricing | Free tier + paid | Free and open source |
| Offline | Desktop app | Full offline |
| Scripting | JavaScript | JavaScript |
| CI/CD | Newman CLI | Bruno CLI |
| Schema | JSON | Plain text .bru |
| Best For | Teams, API documentation | Git workflows, privacy |
When to Use Each
Choose Postman when:
- Team needs real-time collaboration
- API documentation is primary output
- Mock servers needed for frontend dev
- Complex OAuth flows with token refresh
Choose Bruno when:
- Git-native workflow preferred
- Privacy/self-hosting required
- Simpler test scenarios
- Developers prefer code-like syntax </tool_comparison>
<collection_organization>
Collection Structure
Folder Hierarchy
my-api-tests/
├── auth/
│ ├── login.bru
│ ├── refresh-token.bru
│ └── logout.bru
├── users/
│ ├── create-user.bru
│ ├── get-user.bru
│ ├── update-user.bru
│ └── delete-user.bru
├── orders/
│ ├── create-order.bru
│ ├── get-orders.bru
│ └── cancel-order.bru
├── environments/
│ ├── local.bru
│ ├── staging.bru
│ └── production.bru
└── collection.bru
Naming Conventions
| Element | Convention | Example |
|---|---|---|
| Folders | kebab-case, plural | users, auth-flows |
| Requests | verb-noun | create-user, get-orders |
| Variables | camelCase | {{baseUrl}}, {{authToken}} |
| Environments | lowercase | local, staging, production |
Request Ordering
Use sequence numbers for dependent requests:
1. auth/login.bru (seq: 1)
2. users/create-user.bru (seq: 2) - needs auth token
3. users/get-user.bru (seq: 3) - uses created user ID
</collection_organization>
<test_patterns>
Test Assertion Patterns
| Assertion Type | What to Check | Example |
|---|---|---|
| Status codes | 200, 201, 400, 401, 404 | pm.response.to.have.status(200) |
| Response body | Required fields, types, patterns | pm.expect(json).to.have.property("id") |
| Response time | Under threshold | pm.expect(pm.response.responseTime).to.be.below(500) |
| Headers | Content-Type, X-Request-Id | pm.response.to.have.header("Content-Type") |
| JSON schema | Full schema validation | pm.response.to.have.jsonSchema(schema) |
See reference/test-design.md for full assertion patterns with Postman and Bruno examples.
</test_patterns>
<environment_management>
Environment Management
Variable scope (Postman): Global → Collection → Environment → Data → Local (highest priority).
Use environment files for baseUrl, apiKey per env (local/staging/production). Chain requests by saving response values (pm.environment.set("authToken", json.accessToken)) for use in subsequent requests.
See reference/data-management.md for environment file formats, dynamic variables, and request chaining patterns.
</environment_management>
<authentication_testing>
Authentication Testing
| Auth Type | Method | Key Pattern |
|---|---|---|
| Bearer token | Save from login response, use in Authorization header |
pm.environment.set("accessToken", json.accessToken) |
| API key | Header (X-API-Key) or query param |
{{apiKey}} variable |
| OAuth 2.0 | Pre-request script checks expiry, refreshes automatically | pm.sendRequest() for token refresh |
Always test: 401 without token, 403 with wrong role.
See reference/postman-patterns.md for OAuth 2.0 refresh flow and auth failure test patterns.
</authentication_testing>
<error_testing>
Error Response Testing
Test each error class: 400 (validation errors with details array), 404 (not found), 429 (rate limit headers present), 5xx (has requestId).
See reference/test-design.md for error response assertion patterns.
</error_testing>
<ci_integration>
CI/CD Integration
| Tool | CLI | Run Command |
|---|---|---|
| Postman | Newman | newman run collection.json -e staging.json |
| Bruno | Bruno CLI | bru run --env staging |
Integrate via GitHub Actions: install CLI, run collection, upload HTML report as artifact. Use ${{ secrets.* }} for sensitive env vars.
See reference/ci-integration.md for GitHub Actions workflow, reporters, and secrets handling.
</ci_integration>
<data_management>
Test Data Management
Use data files (newman run -d test-data.json) for iteration-based testing. Postman has built-in dynamic variables ({{$guid}}, {{$randomEmail}}, {{$timestamp}}). Add cleanup scripts in post-request to delete created resources.
See reference/data-management.md for data file formats, dynamic generation, and cleanup patterns.
</data_management>
Before creating collection:
- API documentation reviewed
- Authentication method identified
- Base URLs for all environments defined
- Test data strategy determined
For each endpoint:
- Happy path test (expected input, expected output)
- Required field validation (400 errors)
- Authentication test (401 without token)
- Authorization test (403 wrong permissions)
- Not found test (404 invalid ID)
- Response schema validated
- Response time asserted
Collection organization:
- Requests grouped by resource
- Sequence numbers for dependent requests
- Environments for local/staging/production
- Sensitive values marked as secrets
CI integration:
- Newman/Bruno CLI configured
- GitHub Actions workflow created
- Test reports uploaded as artifacts
- Secrets stored in CI environment
| Topic | Reference File | When to Load |
|---|---|---|
| Postman advanced patterns | reference/postman-patterns.md |
Collections, scripting, monitors |
| Bruno workflow | reference/bruno-patterns.md |
.bru files, git integration |
| Test case design | reference/test-design.md |
Coverage strategies, edge cases |
| Test data strategies | reference/data-management.md |
Fixtures, dynamic data, cleanup |
| CI/CD pipelines | reference/ci-integration.md |
Newman, GitHub Actions, reporting |
To load: Ask for the specific topic or check if context suggests it.
Emit Outcome Sidecar
As the final step, write to ~/.claude/skill-analytics/last-outcome-api-testing.json:
{"ts":"[UTC ISO8601]","skill":"api-testing","version":"1.0.0","variant":"default",
"status":"[success|partial|error]","runtime_ms":[estimated ms from start],
"metrics":{"tests_created":[n],"endpoints_tested":[n],"assertions_written":[n]},
"error":null,"session_id":"[YYYY-MM-DD]"}
Use status "partial" if some stages failed but results were produced. Use "error" only if no output was generated.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
project-context
Maintains project context and progress tracking across Claude sessions. Use at session start to load context, on session end to save progress. Triggers: load project context, save context, end session, what was I working on, switch to project, done for today.
workflow-enforcer-skill
Enforces workflow discipline across ALL projects. Ensures Claude checks for specialized agents before responding, announces skill/agent usage, and creates TodoWrite todos for multi-step tasks. Triggers: automatic on all sessions, use the right agent, follow workflow.
gtm-pricing
B2B go-to-market strategy, pricing models, ICP development, positioning, and competitive intelligence. Use when planning GTM strategy, setting pricing, defining ICP, or evaluating opportunities.
subagent-teams
Orchestrate in-session Task tool teams for parallel work. Fan-out research, implementation, review, and documentation across subagents. Use when: parallel tasks, fan-out, subagent team, Task tool, in-session agents.
planning-prompts
Comprehensive skill for project planning and prompt engineering. Covers hierarchical plans (briefs, roadmaps, phases), Claude-to-Claude meta-prompts, and multi-stage workflows. Use when: planning, prompt creation, agentic pipeline work, project roadmap, meta-prompts, research to implement workflow.
linkedin-sales-navigator-alt-skill
Build targeted prospect lists by analyzing LinkedIn profiles, extracting job titles, companies, locations, and recent activity. Identifies decision-makers, tracks job changes for warm outreach, and enriches contact data. Use when users need to find prospects, build lead lists, or track decision-maker movements.
Didn't find tool you were looking for?