用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/microwind/ai-skills --skill api命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | API测试器 |
| description | 当测试API、发送HTTP请求、调试响应或验证端点时,在集成前测试HTTP API并验证响应。 |
| license | MIT |
API是系统之间的连接器。损坏的API会破坏应用程序。在集成前彻底测试端点。
核心原则: API契约必须在部署前验证。
始终:
触发短语:
问题:
API返回不正确的HTTP状态码
错误示例:
POST /api/users → 200 OK (应该是 201 Created)
GET /api/users/999 → 200 OK (应该是 404 Not Found)
PUT /api/users/999 → 200 OK (应该是 404 Not Found)
解决方案:
- 201: 资源创建成功
- 400: 请求参数错误
- 401: 未认证
- 403: 权限不足
- 404: 资源不存在
- 500: 服务器内部错误
问题:
API响应格式不统一
错误示例:
成功响应:
{
"data": {"id": 1, "name": "John"}
}
错误响应:
{
"error": "User not found",
"code": 404
}
解决方案:
统一响应格式:
{
"success": true,
"data": {...},
"message": "操作成功",
"timestamp": "2023-01-01T10:00:00Z"
}
问题:
API认证配置错误
错误示例:
- 缺少认证头
- Token过期处理不当
- 权限检查缺失
解决方案:
1. 实现标准的认证机制
2. 正确处理Token过期
3. 细粒度权限控制
4. 安全的Token生成
import requests
import json
import time
from typing import Dict, List, Any, Optional, Union
from dataclasses import dataclass
from enum import Enum
import concurrent.futures
import statistics
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
import jwt
class HTTPMethod(Enum):
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
PATCH = "PATCH"
HEAD = "HEAD"
OPTIONS = "OPTIONS"
class AuthType(Enum):
NONE = "none"
BASIC = "basic"
DIGEST = "digest"
BEARER = "bearer"
API_KEY = "api_key"
@dataclass
class APIRequest:
"""API请求"""
method: HTTPMethod
url: str
headers: Dict[str, str] = None
params: Dict[str, Any] = None
data: Dict[, ] =
json_data: [, ] =
auth_type: AuthType = AuthType.NONE
auth_credentials: [, ] =
timeout: =
:
status_code:
headers: [, ]
content:
json_data: [[, ]] =
response_time: =
success: =
:
request: APIRequest
response: APIResponse
passed:
errors: []
warnings: []
:
total_requests:
successful_requests:
failed_requests:
avg_response_time:
min_response_time:
max_response_time:
p95_response_time:
requests_per_second:
:
():
.session = requests.Session()
.default_headers = {
: ,
: ,
:
}
() -> APIResponse:
start_time = time.time()
:
headers = {**.default_headers, **(request.headers {})}
auth = ._prepare_auth(request.auth_type, request.auth_credentials)
response = .session.request(
method=request.method.value,
url=request.url,
headers=headers,
params=request.params,
data=request.data,
json=request.json_data,
auth=auth,
timeout=request.timeout
)
response_time = time.time() - start_time
json_data =
:
json_data = response.json()
:
success = <= response.status_code <
APIResponse(
status_code=response.status_code,
headers=(response.headers),
content=response.text,
json_data=json_data,
response_time=response_time,
success=success
)
requests.exceptions.Timeout:
APIResponse(
status_code=,
headers={},
content=,
response_time=time.time() - start_time,
success=
)
requests.exceptions.ConnectionError:
APIResponse(
status_code=,
headers={},
content=,
response_time=time.time() - start_time,
success=
)
Exception e:
APIResponse(
status_code=,
headers={},
content=,
response_time=time.time() - start_time,
success=
)
():
auth_type == AuthType.BASIC:
HTTPBasicAuth(
credentials[],
credentials[]
)
auth_type == AuthType.DIGEST:
HTTPDigestAuth(
credentials[],
credentials[]
)
auth_type == AuthType.BEARER:
auth_type == AuthType.API_KEY:
:
() -> APITestResult:
headers = request.headers {}
request.auth_type == AuthType.BEARER:
headers[] =
request.auth_type == AuthType.API_KEY:
key_name = request.auth_credentials.get(, )
headers[key_name] = request.auth_credentials[]
request.headers = headers
response = .send_request(request)
errors = []
warnings = []
passed =
response.status_code != expected_status:
errors.append()
passed =
response.response_time > :
warnings.append()
expected_schema response.json_data:
schema_errors = ._validate_json_schema(response.json_data, expected_schema)
schema_errors:
errors.extend(schema_errors)
passed =
APITestResult(
request=request,
response=response,
passed=passed,
errors=errors,
warnings=warnings
)
() -> []:
errors = []
schema:
field schema[]:
field data:
errors.append()
schema:
field, field_schema schema[].items():
field data:
value = data[field]
expected_type = field_schema.get()
expected_type == (value, ):
errors.append()
expected_type == (value, (, )):
errors.append()
expected_type == (value, ):
errors.append()
expected_type == (value, ):
errors.append()
expected_type == (value, ):
errors.append()
errors
() -> PerformanceTestResult:
results = []
():
.send_request(request)
concurrent.futures.ThreadPoolExecutor(max_workers=concurrent_users) executor:
futures = [executor.submit(send_single_request) _ (total_requests)]
future concurrent.futures.as_completed(futures):
:
response = future.result()
results.append(response)
Exception e:
()
successful_requests = [r r results r.success]
failed_requests = (results) - (successful_requests)
response_times = [r.response_time r successful_requests]
response_times:
avg_response_time = statistics.mean(response_times)
min_response_time = (response_times)
max_response_time = (response_times)
p95_response_time = (response_times)[((response_times) * )]
:
avg_response_time = min_response_time = max_response_time = p95_response_time =
total_time = (r.response_time r results) results
requests_per_second = (successful_requests) / total_time total_time >
PerformanceTestResult(
total_requests=total_requests,
successful_requests=(successful_requests),
failed_requests=failed_requests,
avg_response_time=avg_response_time,
min_response_time=min_response_time,
max_response_time=max_response_time,
p95_response_time=p95_response_time,
requests_per_second=requests_per_second
)
() -> :
test_results:
report = []
total_tests = (test_results)
passed_tests = ([r r test_results r.passed])
failed_tests = total_tests - passed_tests
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
i, result (test_results, ):
status = result.passed
report.append()
result.response:
report.append()
report.append()
result.errors:
report.append()
error result.errors:
report.append()
result.warnings:
report.append()
warning result.warnings:
report.append()
report.append()
.join(report)
() -> :
report = []
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
.join(report)
():
tester = APITester()
request = APIRequest(
method=HTTPMethod.GET,
url=,
headers={: }
)
result = tester.test_api_endpoint(request, expected_status=)
report = tester.generate_test_report([result])
(report)
perf_result = tester.performance_test(request, concurrent_users=, total_requests=)
perf_report = tester.generate_performance_report(perf_result)
( + perf_report)
__name__ == :
main()
import yaml
from typing import List, Dict, Any
import json
class APITestSuite:
"""API测试套件"""
def __init__(self):
self.tester = APITester()
self.test_cases = []
def load_test_suite(self, suite_file: str) -> bool:
"""加载测试套件"""
try:
with open(suite_file, 'r', encoding='utf-8') as f:
if suite_file.endswith('.yaml') or suite_file.endswith('.yml'):
suite_data = yaml.safe_load(f)
else:
suite_data = json.load(f)
# 解析测试用例
for test_case in suite_data.get('test_cases', []):
self.test_cases.append(self._parse_test_case(test_case))
return True
except Exception as e:
print(f"加载测试套件失败: {str(e)}")
return
() -> [, ]:
{
: test_case_data.get(, ),
: test_case_data.get(, ),
: APIRequest(
method=HTTPMethod(test_case_data[][]),
url=test_case_data[][],
headers=test_case_data[].get(),
params=test_case_data[].get(),
data=test_case_data[].get(),
json_data=test_case_data[].get(),
auth_type=AuthType(test_case_data[].get(, )),
auth_credentials=test_case_data[].get(),
timeout=test_case_data[].get(, )
),
: test_case_data.get(, ),
: test_case_data.get(),
: test_case_data.get(),
: test_case_data.get()
}
() -> [APITestResult]:
results = []
test_case .test_cases:
()
test_case.get():
._execute_setup(test_case[])
result = .tester.test_api_endpoint(
test_case[],
test_case[],
test_case[]
)
result.test_name = test_case[]
results.append(result)
test_case.get():
._execute_teardown(test_case[])
results
():
():
() -> :
results:
report = []
total_tests = (results)
passed_tests = ([r r results r.passed])
failed_tests = total_tests - passed_tests
report.append()
report.append()
report.append()
report.append()
report.append()
report.append()
result results:
test_name = (result, , )
status = result.passed
report.append()
report.append()
report.append()
report.append()
report.append()
result.errors:
report.append()
error result.errors:
report.append()
result.warnings:
report.append()
warning result.warnings:
report.append()
report.append()
.join(report)
():
suite = APITestSuite()
suite.load_test_suite():
results = suite.run_test_suite()
report = suite.generate_suite_report(results)
(report)
__name__ == :
main()