Skill: zhanghengyi1986-afk/qa-api-tester (version 1.0.0)

--- 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) ```bash # 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":"[REDACTED_SECRET]"}' \ "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: ```python """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": "[REDACTED_SECRET]"} 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: ```bash # 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): ```python 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 [REDACTED_SECRET])["token"] headers = {"Authorization": f"Bearer {token}"} # Step 2: Create user = requests.post(f"{BASE_URL}/users", json={"name": "E2E Test", "email": "[REDACTED_SECRET]"}, 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: ```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: ```python 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 ```bash # 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 管理多环境配置，避免硬编码： ```python 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`


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)