API端点测试专家Skill api-tester

该技能提供全面的API端点测试功能,包括HTTP方法验证、请求响应检查、性能测试和安全测试,适用于开发、测试和DevOps团队,确保API的质量和可靠性。关键词:API测试、端点验证、性能基准、安全扫描、自动化测试、负载测试。

测试 0 次安装 0 次浏览 更新于 3/11/2026

name: api-tester description: 快速API端点测试,包含全面的请求/响应验证。

API测试器技能

快速API端点测试,包含全面的请求/响应验证。

指令

您是一个API测试专家。当调用时:

  1. 测试API端点

    • 验证HTTP方法(GET、POST、PUT、PATCH、DELETE)
    • 测试请求头和正文格式
    • 验证响应状态码
    • 验证响应模式和数据类型
    • 检查认证和授权
  2. 生成测试用例

    • 创建用于测试的curl命令
    • 生成Postman集合
    • 编写自动化测试脚本
    • 测试边界情况和错误场景
    • 验证API契约
  3. 性能测试

    • 使用并发请求进行负载测试
    • 响应时间基准测试
    • 速率限制验证
    • 超时处理
    • 连接池测试
  4. 安全测试

    • 认证/授权检查
    • 输入验证测试
    • SQL注入预防
    • XSS预防
    • CORS配置

使用示例

@api-tester
@api-tester --endpoint /api/users
@api-tester --method POST
@api-tester --load-test
@api-tester --generate-collection

REST API测试

GET请求示例

基本GET请求

# curl
curl -X GET https://api.example.com/api/users \
  -H "Content-Type: application/json"

# 带认证
curl -X GET https://api.example.com/api/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json"

# 带查询参数
curl -X GET "https://api.example.com/api/users?page=1&limit=10&sort=created_at" \
  -H "Authorization: Bearer YOUR_TOKEN"

# 详细输出(包含头信息)
curl -v -X GET https://api.example.com/api/users

JavaScript/Node.js

// 使用fetch
async function getUsers() {
  const response = await fetch('https://api.example.com/api/users', {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP错误!状态码:${response.status}`);
  }

  const data = await response.json();
  return data;
}

// 使用axios
const axios = require('axios');

async function getUsers() {
  try {
    const response = await axios.get('https://api.example.com/api/users', {
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN'
      },
      params: {
        page: 1,
        limit: 10
      }
    });
    return response.data;
  } catch (error) {
    console.error('错误:', error.response?.data || error.message);
    throw error;
  }
}

Python

import requests

# 基本GET请求
response = requests.get('https://api.example.com/api/users')
print(response.json())

# 带认证和参数
headers = {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json'
}

params = {
    'page': 1,
    'limit': 10,
    'sort': 'created_at'
}

response = requests.get(
    'https://api.example.com/api/users',
    headers=headers,
    params=params
)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f"错误:{response.status_code}")
    print(response.text)

POST请求示例

创建资源

# curl
curl -X POST https://api.example.com/api/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "role": "user"
  }'

# 从文件
curl -X POST https://api.example.com/api/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d @user.json

JavaScript/Node.js

// 使用fetch
async function createUser(userData) {
  const response = await fetch('https://api.example.com/api/users', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(userData)
  });

  const data = await response.json();
  return data;
}

// 使用
const newUser = {
  name: 'John Doe',
  email: 'john@example.com',
  role: 'user'
};

createUser(newUser)
  .then(user => console.log('已创建:', user))
  .catch(error => console.error('错误:', error));

// 使用axios带错误处理
async function createUser(userData) {
  try {
    const response = await axios.post(
      'https://api.example.com/api/users',
      userData,
      {
        headers: {
          'Authorization': 'Bearer YOUR_TOKEN'
        }
      }
    );
    return response.data;
  } catch (error) {
    if (error.response) {
      // 服务器响应错误
      console.error('错误:', error.response.status);
      console.error('消息:', error.response.data);
    } else if (error.request) {
      // 未收到响应
      console.error('服务器无响应');
    } else {
      console.error('错误:', error.message);
    }
    throw error;
  }
}

Python

import requests

# 创建用户
user_data = {
    'name': 'John Doe',
    'email': 'john@example.com',
    'role': 'user'
}

headers = {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json'
}

response = requests.post(
    'https://api.example.com/api/users',
    json=user_data,
    headers=headers
)

if response.status_code == 201:
    print('用户已创建:', response.json())
else:
    print(f'错误:{response.status_code}')
    print(response.json())

PUT/PATCH请求示例

# PUT - 替换整个资源
curl -X PUT https://api.example.com/api/users/123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Updated",
    "email": "john.updated@example.com",
    "role": "admin"
  }'

# PATCH - 部分更新
curl -X PATCH https://api.example.com/api/users/123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "admin"
  }'

DELETE请求示例

# 删除资源
curl -X DELETE https://api.example.com/api/users/123 \
  -H "Authorization: Bearer YOUR_TOKEN"

# 带确认删除
curl -X DELETE https://api.example.com/api/users/123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "X-Confirm-Delete: true"

认证示例

Bearer令牌(JWT)

# 获取令牌
curl -X POST https://api.example.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123"
  }'

# 使用令牌
curl -X GET https://api.example.com/api/users \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

API密钥

# 在头中
curl -X GET https://api.example.com/api/users \
  -H "X-API-Key: your-api-key-here"

# 在查询参数中
curl -X GET "https://api.example.com/api/users?api_key=your-api-key-here"

基本认证

# 用户名和密码
curl -X GET https://api.example.com/api/users \
  -u username:password

# Base64编码
curl -X GET https://api.example.com/api/users \
  -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="

OAuth 2.0

// 获取访问令牌
async function getAccessToken() {
  const response = await fetch('https://oauth.example.com/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET'
    })
  });

  const data = await response.json();
  return data.access_token;
}

// 使用访问令牌
async function callAPI() {
  const token = await getAccessToken();

  const response = await fetch('https://api.example.com/api/users', {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  return response.json();
}

GraphQL测试

基本查询

# curl
curl -X POST https://api.example.com/graphql \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ users { id name email } }"
  }'

# 带变量
curl -X POST https://api.example.com/graphql \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query GetUser($id: ID!) { user(id: $id) { id name email } }",
    "variables": { "id": "123" }
  }'

GraphQL突变

// 创建用户突变
async function createUser(name, email) {
  const query = `
    mutation CreateUser($name: String!, $email: String!) {
      createUser(input: { name: $name, email: $email }) {
        id
        name
        email
        createdAt
      }
    }
  `;

  const response = await fetch('https://api.example.com/graphql', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      query,
      variables: { name, email }
    })
  });

  const data = await response.json();
  return data.data.createUser;
}

自动化测试

Jest测试套件

const axios = require('axios');

describe('用户API测试', () => {
  const API_URL = 'https://api.example.com';
  const token = 'YOUR_TEST_TOKEN';

  const api = axios.create({
    baseURL: API_URL,
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  describe('GET /api/users', () => {
    test('应返回用户列表', async () => {
      const response = await api.get('/api/users');

      expect(response.status).toBe(200);
      expect(Array.isArray(response.data)).toBe(true);
      expect(response.data.length).toBeGreaterThan(0);
    });

    test('应通过ID返回用户', async () => {
      const response = await api.get('/api/users/123');

      expect(response.status).toBe(200);
      expect(response.data).toHaveProperty('id', '123');
      expect(response.data).toHaveProperty('name');
      expect(response.data).toHaveProperty('email');
    });

    test('对于不存在的用户应返回404', async () => {
      try {
        await api.get('/api/users/999999');
      } catch (error) {
        expect(error.response.status).toBe(404);
      }
    });
  });

  describe('POST /api/users', () => {
    test('应创建新用户', async () => {
      const newUser = {
        name: 'Test User',
        email: 'test@example.com'
      };

      const response = await api.post('/api/users', newUser);

      expect(response.status).toBe(201);
      expect(response.data).toHaveProperty('id');
      expect(response.data.name).toBe(newUser.name);
      expect(response.data.email).toBe(newUser.email);
    });

    test('应验证必填字段', async () => {
      const invalidUser = { name: 'Test' }; // 缺少email

      try {
        await api.post('/api/users', invalidUser);
      } catch (error) {
        expect(error.response.status).toBe(400);
        expect(error.response.data).toHaveProperty('error');
      }
    });

    test('应防止重复邮箱', async () => {
      const user = {
        name: 'Duplicate',
        email: 'existing@example.com'
      };

      try {
        await api.post('/api/users', user);
      } catch (error) {
        expect(error.response.status).toBe(409);
      }
    });
  });

  describe('认证', () => {
    test('应拒绝无令牌的请求', async () => {
      const noAuthAPI = axios.create({ baseURL: API_URL });

      try {
        await noAuthAPI.get('/api/users');
      } catch (error) {
        expect(error.response.status).toBe(401);
      }
    });

    test('应拒绝无效令牌', async () => {
      const badAuthAPI = axios.create({
        baseURL: API_URL,
        headers: { 'Authorization': 'Bearer invalid-token' }
      });

      try {
        await badAuthAPI.get('/api/users');
      } catch (error) {
        expect(error.response.status).toBe(401);
      }
    });
  });
});

Python pytest

import pytest
import requests

API_URL = 'https://api.example.com'
TOKEN = 'YOUR_TEST_TOKEN'

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

def test_get_users(headers):
    response = requests.get(f'{API_URL}/api/users', headers=headers)

    assert response.status_code == 200
    assert isinstance(response.json(), list)
    assert len(response.json()) > 0

def test_get_user_by_id(headers):
    response = requests.get(f'{API_URL}/api/users/123', headers=headers)

    assert response.status_code == 200
    data = response.json()
    assert data['id'] == '123'
    assert 'name' in data
    assert 'email' in data

def test_create_user(headers):
    user_data = {
        'name': 'Test User',
        'email': 'test@example.com'
    }

    response = requests.post(
        f'{API_URL}/api/users',
        json=user_data,
        headers=headers
    )

    assert response.status_code == 201
    data = response.json()
    assert 'id' in data
    assert data['name'] == user_data['name']

def test_unauthorized_access():
    response = requests.get(f'{API_URL}/api/users')
    assert response.status_code == 401

Postman集合

集合结构

{
  "info": {
    "name": "API测试集合",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{access_token}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "用户",
      "item": [
        {
          "name": "获取所有用户",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/api/users?page=1&limit=10",
              "host": ["{{base_url}}"],
              "path": ["api", "users"],
              "query": [
                { "key": "page", "value": "1" },
                { "key": "limit", "value": "10" }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test('状态码为200', function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test('响应为数组', function () {",
                  "    var jsonData = pm.response.json();",
                  "    pm.expect(jsonData).to.be.an('array');",
                  "});"
                ]
              }
            }
          ]
        },
        {
          "name": "创建用户",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{
  \"name\": \"{{$randomFullName}}\",
  \"email\": \"{{$randomEmail}}\",
  \"role\": \"user\"
}"
            },
            "url": {
              "raw": "{{base_url}}/api/users",
              "host": ["{{base_url}}"],
              "path": ["api", "users"]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test('状态码为201', function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "",
                  "pm.test('用户有ID', function () {",
                  "    var jsonData = pm.response.json();",
                  "    pm.expect(jsonData).to.have.property('id');",
                  "    pm.environment.set('user_id', jsonData.id);",
                  "});"
                ]
              }
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.example.com"
    }
  ]
}

负载测试

使用Apache Bench

# 1000个请求,10个并发
ab -n 1000 -c 10 -H "Authorization: Bearer TOKEN" \
  https://api.example.com/api/users

# POST请求带JSON
ab -n 1000 -c 10 -p data.json -T application/json \
  -H "Authorization: Bearer TOKEN" \
  https://api.example.com/api/users

使用Artillery

# artillery.yml
config:
  target: 'https://api.example.com'
  phases:
    - duration: 60
      arrivalRate: 10
      name: 预热
    - duration: 300
      arrivalRate: 50
      name: 持续负载
  defaults:
    headers:
      Authorization: 'Bearer YOUR_TOKEN'

scenarios:
  - name: "获取用户"
    flow:
      - get:
          url: "/api/users"
          expect:
            - statusCode: 200
      - think: 1
      - post:
          url: "/api/users"
          json:
            name: "Test User"
            email: "test@example.com"
          expect:
            - statusCode: 201
# 运行负载测试
artillery run artillery.yml

# 生成HTML报告
artillery run artillery.yml --output report.json
artillery report report.json --output report.html

响应验证

模式验证

const Ajv = require('ajv');
const ajv = new Ajv();

// 定义模式
const userSchema = {
  type: 'object',
  properties: {
    id: { type: 'string' },
    name: { type: 'string' },
    email: { type: 'string', format: 'email' },
    role: { type: 'string', enum: ['user', 'admin'] },
    createdAt: { type: 'string', format: 'date-time' }
  },
  required: ['id', 'name', 'email', 'role']
};

const validate = ajv.compile(userSchema);

// 验证响应
async function testUserAPI() {
  const response = await fetch('https://api.example.com/api/users/123');
  const data = await response.json();

  const valid = validate(data);
  if (!valid) {
    console.error('验证错误:', validate.errors);
  } else {
    console.log('响应有效!');
  }
}

最佳实践

请求最佳实践

  • 始终设置适当的Content-Type
  • 使用正确的HTTP方法(GET用于读取,POST用于创建等)
  • 安全地包含认证令牌
  • 处理超时和重试
  • 发送前验证输入
  • 生产API使用HTTPS

响应处理

  • 解析前检查状态码
  • 优雅地处理错误
  • 验证响应模式
  • 记录请求和响应以进行调试
  • 为重试实现指数退避

安全测试

  • 使用无效令牌测试
  • 测试无认证情况
  • 尝试在参数中进行SQL注入
  • 测试输入字段中的XSS
  • 验证CORS设置
  • 测试速率限制

要测试的错误场景

  • 无效认证
  • 缺少必填字段
  • 无效数据类型
  • 重复资源
  • 未找到(404)
  • 服务器错误(500)
  • 速率限制超出(429)
  • 网络超时

常见HTTP状态码

200 OK - 请求成功
201 Created - 资源已创建
204 No Content - 成功,无响应体
400 Bad Request - 无效请求
401 Unauthorized - 缺少/无效认证
403 Forbidden - 不允许访问
404 Not Found - 资源不存在
409 Conflict - 资源已存在
422 Unprocessable Entity - 验证失败
429 Too Many Requests - 速率限制超出
500 Internal Server Error - 服务器错误
502 Bad Gateway - 上游服务器错误
503 Service Unavailable - 服务器过载

备注

  • 始终在开发/预生产环境中测试
  • 使用环境变量存储API URL和令牌
  • 记录所有测试用例和预期结果
  • 在CI/CD管道中自动化测试
  • 监控API性能和错误率
  • 保持Postman集合更新
  • 测试边界情况和错误场景
  • 验证成功和失败路径
  • 使用适当的认证方法
  • 切勿将API密钥或令牌提交到版本控制