🎁 Get the FREE AI Skills Starter GuideSubscribe →
BytesAgainBytesAgain
🦀 ClawHub

QA API Tester

by @zhanghengyi1986-afk

API interface testing and automation. Send HTTP requests, validate responses, chain API calls, generate test scripts (Python requests/pytest, curl, Postman c...

TERMINAL
clawhub install qa-api-tester

📖 About This Skill


name: api-tester description: > API interface testing and automation. Send HTTP requests, validate responses, chain API calls, generate test scripts (Python requests/pytest, curl, Postman collections). Use when: (1) testing API endpoints, (2) writing API test scripts, (3) validating response schema/status/data, (4) stress testing APIs, (5) generating Postman collections, (6) "接口测试", "API测试", "发请求", "压测接口", "生成Postman集合". NOT for: UI/browser testing (use web-tester), database testing, or test case design without execution (use test-case-gen). metadata: openclaw: emoji: "🧪" requires: bins: [curl, python3]

API Tester

Test, validate, and automate API interfaces.

When to Use

USE this skill when:

  • Testing REST/GraphQL API endpoints
  • Validating response status, headers, body, schema
  • Writing pytest/requests API test scripts
  • Generating Postman/Insomnia collections
  • Chaining multi-step API workflows (auth → CRUD → verify)
  • "帮我测一下这个接口" / "写个接口自动化脚本"
  • DON'T use this skill when:

  • Browser/UI testing → use web automation tools
  • Designing test cases without execution → use test-case-gen
  • Load testing at scale → use dedicated tools (JMeter, k6, locust)
  • Quick API Testing

    Single Request (curl)

    # GET
    curl -s -w "\n%{http_code} %{time_total}s" \
      -H "Authorization: Bearer $TOKEN" \
      "https://api.example.com/users/1" | jq .

    POST with JSON body

    curl -s -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{"name":"test","email":"test@example.com"}' \ "https://api.example.com/users" | jq .

    PUT / PATCH / DELETE similar pattern

    Response Validation Checklist

    For each API response, verify:

  • [ ] Status code: Matches expected (200/201/400/401/403/404/500)
  • [ ] Response time: Within SLA (e.g., < 500ms)
  • [ ] Content-Type: Correct (application/json, etc.)
  • [ ] Body structure: Required fields present, correct types
  • [ ] Data accuracy: Values match expected business logic
  • [ ] Error format: Error responses follow consistent schema
  • [ ] Headers: Security headers present (CORS, CSP, etc.)
  • Automation Script Generation

    Python pytest + requests

    When user asks for automated API tests, generate this structure:

    """API Test Suite - {module_name}
    Generated by 虫探 🔍
    """
    import pytest
    import requests

    BASE_URL = "https://api.example.com" TOKEN = "" # Set via env or fixture

    @pytest.fixture def auth_headers(): return {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

    class TestUserAPI: """User module API tests"""

    def test_get_user_success(self, auth_headers): """TC001: Get user by valid ID""" resp = requests.get(f"{BASE_URL}/users/1", headers=auth_headers) assert resp.status_code == 200 data = resp.json() assert "id" in data assert "name" in data assert data["id"] == 1

    def test_get_user_not_found(self, auth_headers): """TC002: Get user by non-existent ID""" resp = requests.get(f"{BASE_URL}/users/99999", headers=auth_headers) assert resp.status_code == 404

    def test_create_user_success(self, auth_headers): """TC003: Create user with valid data""" payload = {"name": "Test User", "email": "test@example.com"} resp = requests.post(f"{BASE_URL}/users", json=payload, headers=auth_headers) assert resp.status_code == 201 data = resp.json() assert data["name"] == payload["name"]

    def test_create_user_missing_field(self, auth_headers): """TC004: Create user missing required field""" payload = {"name": "Test User"} # missing email resp = requests.post(f"{BASE_URL}/users", json=payload, headers=auth_headers) assert resp.status_code in (400, 422)

    Save to workspace and run:

    # Save script
    

    Run tests

    cd ~/.openclaw/workspace && python3 -m pytest test_api.py -v --tb=short

    Multi-step Workflow Test

    For complex flows (login → create → verify → delete):

    class TestUserWorkflow:
        """End-to-end user CRUD workflow"""

    def test_full_crud_flow(self): # Step 1: Login resp = requests.post(f"{BASE_URL}/auth/login", json={"username": "admin", "password": "pass"}) assert resp.status_code == 200 token = resp.json()["token"] headers = {"Authorization": f"Bearer {token}"}

    # Step 2: Create user = requests.post(f"{BASE_URL}/users", json={"name": "E2E Test", "email": "e2e@test.com"}, headers=headers) assert user.status_code == 201 user_id = user.json()["id"]

    # Step 3: Read & Verify get_resp = requests.get(f"{BASE_URL}/users/{user_id}", headers=headers) assert get_resp.status_code == 200 assert get_resp.json()["name"] == "E2E Test"

    # Step 4: Update update = requests.put(f"{BASE_URL}/users/{user_id}", json={"name": "Updated"}, headers=headers) assert update.status_code == 200

    # Step 5: Delete delete = requests.delete(f"{BASE_URL}/users/{user_id}", headers=headers) assert delete.status_code in (200, 204)

    # Step 6: Verify deleted verify = requests.get(f"{BASE_URL}/users/{user_id}", headers=headers) assert verify.status_code == 404

    Postman Collection Export

    Generate Postman v2.1 collection JSON:

    {
      "info": {
        "name": "API Test Collection",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
      },
      "variable": [
        {"key": "base_url", "value": "https://api.example.com"},
        {"key": "token", "value": ""}
      ],
      "item": [
        {
          "name": "Auth",
          "item": [
            {
              "name": "Login",
              "request": {
                "method": "POST",
                "url": "{{base_url}}/auth/login",
                "header": [{"key": "Content-Type", "value": "application/json"}],
                "body": {"mode": "raw", "raw": "{\"username\":\"admin\",\"password\":\"pass\"}"}
              }
            }
          ]
        }
      ]
    }
    

    Common Test Scenarios

    Always consider these for any API:

    | Category | Test Points | |----------|-------------| | Auth | No token, expired token, invalid token, wrong role | | Input | Empty body, missing fields, wrong types, overflow values | | Boundary | Max length strings, 0/negative numbers, future/past dates | | Security | SQL injection, XSS in input, path traversal, IDOR | | Concurrency | Duplicate requests, race conditions | | Pagination | page=0, page=-1, huge page_size, beyond last page | | Idempotency | Repeat same PUT/DELETE, check consistency |

    JSON Schema Validation

    When validating API response structure:

    import jsonschema

    user_schema = { "type": "object", "required": ["id", "name", "email"], "properties": { "id": {"type": "integer", "minimum": 1}, "name": {"type": "string", "minLength": 1}, "email": {"type": "string", "format": "email"}, "created_at": {"type": "string", "format": "date-time"} }, "additionalProperties": False }

    def test_user_response_schema(auth_headers): resp = requests.get(f"{BASE_URL}/users/1", headers=auth_headers) jsonschema.validate(resp.json(), user_schema)

    Quick Performance Check

    # Simple latency test (10 requests)
    for i in $(seq 1 10); do
      curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" \
        -H "Authorization: Bearer $TOKEN" \
        "https://api.example.com/users"
    done

    Concurrent requests (requires GNU parallel or xargs)

    seq 1 50 | xargs -P 10 -I {} curl -s -o /dev/null -w "{}: %{http_code} %{time_total}s\n" \ "https://api.example.com/health"

    Environment Management

    管理多环境配置,避免硬编码:

    import os

    ENV_CONFIG = { "dev": {"base_url": "https://dev-api.example.com", "token_env": "DEV_TOKEN"}, "staging": {"base_url": "https://staging-api.example.com", "token_env": "STG_TOKEN"}, "prod": {"base_url": "https://api.example.com", "token_env": "PROD_TOKEN"}, }

    @pytest.fixture def env(): name = os.getenv("TEST_ENV", "dev") cfg = ENV_CONFIG[name] cfg["token"] = os.getenv(cfg["token_env"], "") return cfg

    Run with: TEST_ENV=staging python3 -m pytest test_api.py -v

    ⚡ When to Use

    TriggerAction
    - Testing REST/GraphQL API endpoints
    - Validating response status, headers, body, schema
    - Writing pytest/requests API test scripts
    - Generating Postman/Insomnia collections
    - Chaining multi-step API workflows (auth → CRUD → verify)
    - "帮我测一下这个接口" / "写个接口自动化脚本"
    ❌ **DON'T use this skill when:**
    - Browser/UI testing → use web automation tools
    - Designing test cases without execution → use `test-case-gen`
    - Load testing at scale → use dedicated tools (JMeter, k6, locust)