agentsclimarketplace

Api testing

Skill onfire7777/universal-ai-skills-library/skills/api-testing

Router-first AI skill system for Codex, Claude, Cursor, Hermes, Paperclip, OpenCode, and local AI stacks: search, preflight-route, and load 1,812 skills on demand without duplicating the corpus.

Install
npx -y skills add onfire7777/universal-ai-skills-library --skill api-testing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use for testing HTTP endpoints directly using cross-platform API testing tools. Covers .http files (VS Code REST Client, JetBrains HTTP Client), Bruno collections, Postman/Newman, k6 for functional API verification, environment management, and CI integration patterns. USE FOR: .http files, Bruno, Postman, Newman, REST Client, k6 API tests, HTTP endpoint testing, API collections, environment variables, API functional verification, HTTP request scripting, API test automation DO NOT USE FOR: browser-based testing (use e2e-testing), contract verification between services (use contract-testing), load/stress testing at scale (use performance-testing)

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

14.6 KB, ~3.4k tokens by cl100k_base, as published. Nobody here has run it

API Testing

Overview

API testing verifies HTTP endpoints directly without a browser or UI layer. It validates request/response contracts, status codes, headers, payloads, authentication, and error handling at the transport level. API tests are faster than E2E tests and provide high confidence that your services behave correctly.

Cross-Platform Tools

ToolTypeStrengths
.http filesVS Code REST Client / JetBrains HTTP ClientVersion-controlled, inline in IDE, variable support
BrunoDesktop + CLIGit-friendly .bru collections, open source, no cloud sync required
Postman / NewmanDesktop + CLIRich GUI, team collaboration, extensive scripting, CI via Newman
k6CLI (JavaScript)Scripted API tests with checks and thresholds, doubles as load tool
REST Client (VS Code)VS Code extensionLightweight, .http/.rest files, inline responses

.http Files (VS Code REST Client / JetBrains HTTP Client)

Syntax Overview

The .http file format is supported by both VS Code REST Client and JetBrains HTTP Client with minor differences. Requests are separated by ###.

Example: requests.http

### Variables
@baseUrl = https://api.example.com
@authToken = Bearer {{$dotenv AUTH_TOKEN}}

### GET — List users
GET {{baseUrl}}/users?page=1&limit=10
Authorization: {{authToken}}
Accept: application/json

### POST — Create a user
POST {{baseUrl}}/users
Authorization: {{authToken}}
Content-Type: application/json

{
    "name": "Jane Doe",
    "email": "[email protected]",
    "role": "admin"
}

### PUT — Update user
PUT {{baseUrl}}/users/42
Authorization: {{authToken}}
Content-Type: application/json

{
    "name": "Jane Smith"
}

### DELETE — Remove user
DELETE {{baseUrl}}/users/42
Authorization: {{authToken}}

Environment Files

Create environment-specific variable files for VS Code REST Client:

// .vscode/settings.json
{
    "rest-client.environmentVariables": {
        "$shared": {
            "version": "v1"
        },
        "development": {
            "baseUrl": "http://localhost:3000",
            "authToken": "dev-token-123"
        },
        "staging": {
            "baseUrl": "https://staging-api.example.com",
            "authToken": "staging-token-456"
        },
        "production": {
            "baseUrl": "https://api.example.com",
            "authToken": "prod-token-789"
        }
    }
}

JetBrains HTTP Client Environment

// http-client.env.json
{
    "development": {
        "baseUrl": "http://localhost:3000",
        "authToken": "dev-token-123"
    },
    "staging": {
        "baseUrl": "https://staging-api.example.com",
        "authToken": "staging-token-456"
    }
}
// http-client.private.env.json (gitignored — secrets go here)
{
    "development": {
        "authToken": "real-dev-secret"
    }
}

Bruno

Overview

Bruno is an open-source, git-friendly API client. Collections are stored as plain-text .bru files that can be version-controlled alongside your code.

Example: .bru File Format

// collection/users/get-users.bru
meta {
  name: Get Users
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/users?page=1&limit=10
  body: none
  auth: bearer
}

auth:bearer {
  token: {{authToken}}
}

headers {
  Accept: application/json
}

assert {
  res.status: eq 200
  res.body.length: gt 0
}

script:post-response {
  const data = res.getBody();
  bru.setVar("firstUserId", data[0].id);
}
// collection/users/create-user.bru
meta {
  name: Create User
  type: http
  seq: 2
}

post {
  url: {{baseUrl}}/users
  body: json
  auth: bearer
}

auth:bearer {
  token: {{authToken}}
}

body:json {
  {
    "name": "Jane Doe",
    "email": "[email protected]",
    "role": "admin"
  }
}

assert {
  res.status: eq 201
  res.body.name: eq "Jane Doe"
}

Bruno Environment Files

// environments/development.bru
vars {
  baseUrl: http://localhost:3000
  authToken: dev-token-123
}
// environments/staging.bru
vars {
  baseUrl: https://staging-api.example.com
  authToken: staging-token-456
}

Bruno CLI Runner (CI Integration)

# Install Bruno CLI
npm install -g @usebruno/cli

# Run entire collection
bru run --env development

# Run specific folder
bru run collection/users --env staging

# Output JUnit report for CI
bru run --env staging --output results.xml --format junit

Postman / Newman

Collection Structure

Postman collections are JSON files containing organized API requests with folders, variables, and test scripts.

Pre-Request Scripts

// Pre-request script — generate dynamic data
const timestamp = Date.now();
pm.variables.set("requestId", `req-${timestamp}`);

// Chain authentication
if (!pm.environment.get("accessToken")) {
    pm.sendRequest({
        url: pm.environment.get("authUrl") + "/token",
        method: "POST",
        header: { "Content-Type": "application/json" },
        body: {
            mode: "raw",
            raw: JSON.stringify({
                client_id: pm.environment.get("clientId"),
                client_secret: pm.environment.get("clientSecret"),
                grant_type: "client_credentials"
            })
        }
    }, (err, res) => {
        pm.environment.set("accessToken", res.json().access_token);
    });
}

Post-Response Test Scripts

// Test response status and structure
pm.test("Status code is 200", () => {
    pm.response.to.have.status(200);
});

pm.test("Response has required fields", () => {
    const json = pm.response.json();
    pm.expect(json).to.have.property("id");
    pm.expect(json).to.have.property("name");
    pm.expect(json).to.have.property("email");
});

pm.test("Response time is under 500ms", () => {
    pm.expect(pm.response.responseTime).to.be.below(500);
});

// Store value for chaining
pm.environment.set("userId", pm.response.json().id);

Newman CLI Runner (CI Integration)

# Install Newman
npm install -g newman

# Run collection with environment
newman run collection.json \
    --environment staging.postman_environment.json \
    --reporters cli,junit \
    --reporter-junit-export results.xml

# Run with iteration data
newman run collection.json \
    --environment staging.postman_environment.json \
    --iteration-data test-data.csv \
    --iteration-count 5

# Fail on test errors (for CI gates)
newman run collection.json \
    --environment staging.postman_environment.json \
    --bail

GitHub Actions Integration

# .github/workflows/api-tests.yml
name: API Tests
on: [push, pull_request]

jobs:
  api-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install -g newman newman-reporter-htmlextra
      - run: |
          newman run tests/api/collection.json \
            --environment tests/api/env-staging.json \
            --reporters cli,junit,htmlextra \
            --reporter-junit-export results/junit.xml \
            --reporter-htmlextra-export results/report.html
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: api-test-results
          path: results/

k6 for API Testing

Overview

k6 is typically associated with load testing, but it excels at functional API verification too. Its JavaScript-based scripting, built-in checks, and threshold system make it powerful for API testing in CI pipelines.

Functional API Test with Checks

// tests/api/users.k6.js
import http from "k6/http";
import { check, group } from "k6";

const BASE_URL = __ENV.BASE_URL || "http://localhost:3000";
const AUTH_TOKEN = __ENV.AUTH_TOKEN || "dev-token";

export const options = {
    // For functional testing: 1 VU, 1 iteration
    vus: 1,
    iterations: 1,
    thresholds: {
        checks: ["rate==1.0"],          // All checks must pass
        http_req_duration: ["p(95)<2000"], // 95th percentile under 2s
    },
};

export default function () {
    const headers = {
        Authorization: `Bearer ${AUTH_TOKEN}`,
        "Content-Type": "application/json",
    };

    group("User CRUD operations", () => {
        // CREATE
        const createRes = http.post(
            `${BASE_URL}/users`,
            JSON.stringify({
                name: "Jane Doe",
                email: `jane+${Date.now()}@example.com`,
                role: "admin",
            }),
            { headers }
        );

        check(createRes, {
            "POST /users returns 201": (r) => r.status === 201,
            "POST /users returns user id": (r) => r.json("id") !== undefined,
            "POST /users returns correct name": (r) => r.json("name") === "Jane Doe",
        });

        const userId = createRes.json("id");

        // READ
        const getRes = http.get(`${BASE_URL}/users/${userId}`, { headers });

        check(getRes, {
            "GET /users/:id returns 200": (r) => r.status === 200,
            "GET /users/:id returns correct user": (r) => r.json("id") === userId,
        });

        // UPDATE
        const updateRes = http.put(
            `${BASE_URL}/users/${userId}`,
            JSON.stringify({ name: "Jane Smith" }),
            { headers }
        );

        check(updateRes, {
            "PUT /users/:id returns 200": (r) => r.status === 200,
            "PUT /users/:id updates name": (r) => r.json("name") === "Jane Smith",
        });

        // DELETE
        const deleteRes = http.del(`${BASE_URL}/users/${userId}`, null, { headers });

        check(deleteRes, {
            "DELETE /users/:id returns 204": (r) => r.status === 204,
        });

        // VERIFY DELETION
        const verifyRes = http.get(`${BASE_URL}/users/${userId}`, { headers });

        check(verifyRes, {
            "GET deleted user returns 404": (r) => r.status === 404,
        });
    });
}

Running k6 API Tests

# Run with default settings
k6 run tests/api/users.k6.js

# Run with environment variables
k6 run tests/api/users.k6.js \
    --env BASE_URL=https://staging-api.example.com \
    --env AUTH_TOKEN=staging-token

# Output JSON results for CI
k6 run tests/api/users.k6.js --out json=results.json

# Output JUnit-compatible results (via xk6-junit extension or summary handler)
k6 run tests/api/users.k6.js --summary-export=summary.json

Environment Management Patterns

Pattern: Environment Configuration File

project/
  tests/
    api/
      environments/
        dev.env.json
        staging.env.json
        prod.env.json        # Read-only / smoke tests only
      collections/
        users.http
        orders.http
      k6/
        users.k6.js

Pattern: Shared Variables Across Tools

// environments/staging.env.json — tool-agnostic config
{
    "baseUrl": "https://staging-api.example.com",
    "authUrl": "https://staging-auth.example.com",
    "clientId": "staging-client-id",
    "timeout": 5000,
    "retries": 2
}

Pattern: CI Pipeline with Multiple API Test Tools

# .github/workflows/api-tests.yml
jobs:
  api-tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [staging]
    steps:
      - uses: actions/checkout@v4

      # Run .http file tests via httpyac (CLI runner for .http files)
      - run: npx httpyac tests/api/**/*.http --all --env ${{ matrix.environment }}

      # Run Bruno collection
      - run: npx @usebruno/cli run tests/api/bruno --env ${{ matrix.environment }}

      # Run k6 functional tests
      - run: |
          k6 run tests/api/k6/users.k6.js \
            --env BASE_URL=${{ secrets.STAGING_API_URL }} \
            --env AUTH_TOKEN=${{ secrets.STAGING_AUTH_TOKEN }}

Best Practices

General

  • Version-control your API test collections alongside the code they test.
  • Use environment files to separate configuration from test logic.
  • Never commit secrets — use environment variables, .env files (gitignored), or CI secrets.
  • Assert on response structure, not just status codes — validate required fields, types, and values.
  • Test error cases: 400 (bad input), 401 (unauthorized), 403 (forbidden), 404 (not found), 409 (conflict), 422 (validation), 500 (server error).

.http Files

  • Use ### separators to organize requests logically in a single file.
  • Use @variable declarations at the top for shared values.
  • Use {{$dotenv VAR}} for secrets to avoid hardcoding tokens.
  • Keep .http files next to the API code they test for easy discovery.

Bruno

  • Commit .bru files directly to git — they are designed for version control.
  • Use the assert block for inline response validation.
  • Use script:post-response to chain values between requests.
  • Prefer Bruno over Postman when you need offline, git-native API testing.

Postman / Newman

  • Export collections as v2.1 JSON and commit them to the repository.
  • Use collection-level variables for values shared across requests.
  • Use pm.test() in post-response scripts for assertions.
  • Run Newman in CI with --bail to fail fast on errors.

k6

  • Use vus: 1, iterations: 1 for functional API tests (not load testing).
  • Use check() for assertions and thresholds for pass/fail gates in CI.
  • Group related requests with group() for organized output.
  • Use __ENV for environment-specific configuration.

Environment Management

  • Maintain parallel environment configs for dev, staging, and production.
  • Use read-only / smoke-test-only policies for production environments.
  • Centralize environment configuration in one place and generate tool-specific formats if needed.
  • Document which environments are safe for write operations (POST, PUT, DELETE).

What ships with it: 30 files

28.0 KB alongside SKILL.md

rules/

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.