api-tester

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

API Tester Skill

API Tester 技能

Quick API endpoint testing with comprehensive request/response validation.
快速进行API端点测试,包含全面的请求/响应验证。

Instructions

使用说明

You are an API testing expert. When invoked:
  1. Test API Endpoints:
    • Validate HTTP methods (GET, POST, PUT, PATCH, DELETE)
    • Test request headers and body formats
    • Verify response status codes
    • Validate response schema and data types
    • Check authentication and authorization
  2. Generate Test Cases:
    • Create curl commands for testing
    • Generate Postman collections
    • Write automated test scripts
    • Test edge cases and error scenarios
    • Validate API contracts
  3. Performance Testing:
    • Load testing with concurrent requests
    • Response time benchmarking
    • Rate limit verification
    • Timeout handling
    • Connection pooling tests
  4. Security Testing:
    • Authentication/authorization checks
    • Input validation testing
    • SQL injection prevention
    • XSS prevention
    • CORS configuration
你是一名API测试专家。被调用时:
  1. 测试API端点:
    • 验证HTTP方法(GET、POST、PUT、PATCH、DELETE)
    • 测试请求头和请求体格式
    • 验证响应状态码
    • 校验响应 schema 和数据类型
    • 检查认证与授权
  2. 生成测试用例:
    • 创建用于测试的curl命令
    • 生成Postman集合
    • 编写自动化测试脚本
    • 测试边缘情况和错误场景
    • 验证API契约
  3. 性能测试:
    • 并发请求的负载测试
    • 响应时间基准测试
    • 速率限制验证
    • 超时处理测试
    • 连接池测试
  4. 安全测试:
    • 认证/授权检查
    • 输入验证测试
    • SQL注入防护测试
    • XSS防护测试
    • CORS配置验证

Usage Examples

使用示例

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

REST API Testing

REST API 测试

GET Request Examples

GET 请求示例

Basic GET Request

基础GET请求

bash
undefined
bash
undefined

curl

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 "Content-Type: application/json"

With authentication

带认证

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
-H "Authorization: Bearer YOUR_TOKEN"
-H "Content-Type: application/json"

With query parameters

带查询参数

curl -X GET "https://api.example.com/api/users?page=1&limit=10&sort=created_at"
-H "Authorization: Bearer YOUR_TOKEN"
curl -X GET "https://api.example.com/api/users?page=1&limit=10&sort=created_at"
-H "Authorization: Bearer YOUR_TOKEN"

Verbose output (includes headers)

详细输出(包含请求头)

undefined
undefined

JavaScript/Node.js

JavaScript/Node.js

javascript
// Using 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 error! status: ${response.status}`);
  }

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

// Using 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:', error.response?.data || error.message);
    throw error;
  }
}
javascript
// 使用 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 error! status: ${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:', error.response?.data || error.message);
    throw error;
  }
}

Python

Python

python
import requests
python
import requests

Basic GET request

基础GET请求

response = requests.get('https://api.example.com/api/users') print(response.json())
response = requests.get('https://api.example.com/api/users') print(response.json())

With authentication and parameters

带认证和参数

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"Error: {response.status_code}") print(response.text)
undefined
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"Error: {response.status_code}") print(response.text)
undefined

POST Request Examples

POST 请求示例

Create Resource

创建资源

bash
undefined
bash
undefined

curl

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 '{ "name": "John Doe", "email": "john@example.com", "role": "user" }'

From file

从文件读取

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

JavaScript/Node.js

JavaScript/Node.js

javascript
// Using 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;
}

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

createUser(newUser)
  .then(user => console.log('Created:', user))
  .catch(error => console.error('Error:', error));

// Using axios with error handling
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) {
      // Server responded with error
      console.error('Error:', error.response.status);
      console.error('Message:', error.response.data);
    } else if (error.request) {
      // No response received
      console.error('No response from server');
    } else {
      console.error('Error:', error.message);
    }
    throw error;
  }
}
javascript
// 使用 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('Created:', user))
  .catch(error => console.error('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:', error.response.status);
      console.error('Message:', error.response.data);
    } else if (error.request) {
      // 未收到响应
      console.error('No response from server');
    } else {
      console.error('Error:', error.message);
    }
    throw error;
  }
}

Python

Python

python
import requests
python
import requests

Create user

创建用户

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('User created:', response.json()) else: print(f'Error: {response.status_code}') print(response.json())
undefined
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('User created:', response.json()) else: print(f'Error: {response.status_code}') print(response.json())
undefined

PUT/PATCH Request Examples

PUT/PATCH 请求示例

bash
undefined
bash
undefined

PUT - Replace entire resource

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" }'
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 - Partial update

PATCH - 部分更新

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

DELETE Request Examples

DELETE 请求示例

bash
undefined
bash
undefined

Delete resource

删除资源

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"

Delete with confirmation

带确认的删除

curl -X DELETE https://api.example.com/api/users/123
-H "Authorization: Bearer YOUR_TOKEN"
-H "X-Confirm-Delete: true"
undefined
curl -X DELETE https://api.example.com/api/users/123
-H "Authorization: Bearer YOUR_TOKEN"
-H "X-Confirm-Delete: true"
undefined

Authentication Examples

认证示例

Bearer Token (JWT)

Bearer Token (JWT)

bash
undefined
bash
undefined

Get token

获取令牌

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

Use token

使用令牌

curl -X GET https://api.example.com/api/users
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
undefined
curl -X GET https://api.example.com/api/users
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
undefined

API Key

API Key

bash
undefined
bash
undefined

In header

在请求头中

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
-H "X-API-Key: your-api-key-here"

In query parameter

在查询参数中

Basic Auth

Basic Auth

bash
undefined
bash
undefined

Username and password

用户名和密码

curl -X GET https://api.example.com/api/users
-u username:password
curl -X GET https://api.example.com/api/users
-u username:password

Base64 encoded

Base64编码

curl -X GET https://api.example.com/api/users
-H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="
undefined
curl -X GET https://api.example.com/api/users
-H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="
undefined

OAuth 2.0

OAuth 2.0

javascript
// Get access token
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;
}

// Use 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();
}
javascript
// 获取访问令牌
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 Testing

GraphQL 测试

Basic Query

基础查询

bash
undefined
bash
undefined

curl

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": "{ users { id name email } }" }'

With variables

带变量

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" } }'
undefined
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" } }'
undefined

GraphQL Mutations

GraphQL 变更

javascript
// Create user mutation
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;
}
javascript
// 创建用户变更
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;
}

Automated Testing

自动化测试

Jest Test Suite

Jest 测试套件

javascript
const axios = require('axios');

describe('User API Tests', () => {
  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('should return list of users', 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('should return user by 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('should return 404 for non-existent user', async () => {
      try {
        await api.get('/api/users/999999');
      } catch (error) {
        expect(error.response.status).toBe(404);
      }
    });
  });

  describe('POST /api/users', () => {
    test('should create new user', 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('should validate required fields', async () => {
      const invalidUser = { name: 'Test' }; // missing email

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

    test('should prevent duplicate emails', 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('Authentication', () => {
    test('should reject requests without token', async () => {
      const noAuthAPI = axios.create({ baseURL: API_URL });

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

    test('should reject invalid token', 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);
      }
    });
  });
});
javascript
const axios = require('axios');

describe('User API Tests', () => {
  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('should return list of users', 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('should return user by 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('should return 404 for non-existent user', async () => {
      try {
        await api.get('/api/users/999999');
      } catch (error) {
        expect(error.response.status).toBe(404);
      }
    });
  });

  describe('POST /api/users', () => {
    test('should create new user', 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('should validate required fields', async () => {
      const invalidUser = { name: 'Test' }; // 缺少邮箱

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

    test('should prevent duplicate emails', 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('Authentication', () => {
    test('should reject requests without token', async () => {
      const noAuthAPI = axios.create({ baseURL: API_URL });

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

    test('should reject invalid token', 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

Python pytest

python
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
python
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 Collection

Postman 集合

Collection Structure

集合结构

json
{
  "info": {
    "name": "API Test Collection",
    "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": "Users",
      "item": [
        {
          "name": "Get All Users",
          "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('Status code is 200', function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test('Response is array', function () {",
                  "    var jsonData = pm.response.json();",
                  "    pm.expect(jsonData).to.be.an('array');",
                  "});"
                ]
              }
            }
          ]
        },
        {
          "name": "Create User",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"{{$randomFullName}}\",\n  \"email\": \"{{$randomEmail}}\",\n  \"role\": \"user\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/api/users",
              "host": ["{{base_url}}"],
              "path": ["api", "users"]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test('Status code is 201', function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "",
                  "pm.test('User has 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"
    }
  ]
}
json
{
  "info": {
    "name": "API Test Collection",
    "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": "Users",
      "item": [
        {
          "name": "Get All Users",
          "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('Status code is 200', function () {",
                  "    pm.response.to.have.status(200);",
                  "});",
                  "",
                  "pm.test('Response is array', function () {",
                  "    var jsonData = pm.response.json();",
                  "    pm.expect(jsonData).to.be.an('array');",
                  "});"
                ]
              }
            }
          ]
        },
        {
          "name": "Create User",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"{{$randomFullName}}\",\n  \"email\": \"{{$randomEmail}}\",\n  \"role\": \"user\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/api/users",
              "host": ["{{base_url}}"],
              "path": ["api", "users"]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test('Status code is 201', function () {",
                  "    pm.response.to.have.status(201);",
                  "});",
                  "",
                  "pm.test('User has 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"
    }
  ]
}

Load Testing

负载测试

Using Apache Bench

使用Apache Bench

bash
undefined
bash
undefined

1000 requests, 10 concurrent

1000次请求,10个并发

ab -n 1000 -c 10 -H "Authorization: Bearer TOKEN"
https://api.example.com/api/users
ab -n 1000 -c 10 -H "Authorization: Bearer TOKEN"
https://api.example.com/api/users

POST request with JSON

带JSON的POST请求

ab -n 1000 -c 10 -p data.json -T application/json
-H "Authorization: Bearer TOKEN"
https://api.example.com/api/users
undefined
ab -n 1000 -c 10 -p data.json -T application/json
-H "Authorization: Bearer TOKEN"
https://api.example.com/api/users
undefined

Using Artillery

使用Artillery

yaml
undefined
yaml
undefined

artillery.yml

artillery.yml

config: target: 'https://api.example.com' phases: - duration: 60 arrivalRate: 10 name: Warm up - duration: 300 arrivalRate: 50 name: Sustained load defaults: headers: Authorization: 'Bearer YOUR_TOKEN'
scenarios:
  • name: "Get users" 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

```bash
config: target: 'https://api.example.com' phases: - duration: 60 arrivalRate: 10 name: Warm up - duration: 300 arrivalRate: 50 name: Sustained load defaults: headers: Authorization: 'Bearer YOUR_TOKEN'
scenarios:
  • name: "Get users" 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

```bash

Run load test

运行负载测试

artillery run artillery.yml
artillery run artillery.yml

Generate HTML report

生成HTML报告

artillery run artillery.yml --output report.json artillery report report.json --output report.html
undefined
artillery run artillery.yml --output report.json artillery report report.json --output report.html
undefined

Response Validation

响应验证

Schema Validation

Schema验证

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

// Define schema
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);

// Validate response
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('Validation errors:', validate.errors);
  } else {
    console.log('Response is valid!');
  }
}
javascript
const Ajv = require('ajv');
const ajv = new Ajv();

// 定义schema
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('Validation errors:', validate.errors);
  } else {
    console.log('Response is valid!');
  }
}

Best Practices

最佳实践

Request Best Practices

请求最佳实践

  • Always set appropriate
    Content-Type
    headers
  • Use proper HTTP methods (GET for reads, POST for creates, etc.)
  • Include authentication tokens securely
  • Handle timeouts and retries
  • Validate input before sending
  • Use HTTPS for production APIs
  • 始终设置合适的
    Content-Type
    请求头
  • 使用正确的HTTP方法(GET用于读取,POST用于创建等)
  • 安全地包含认证令牌
  • 处理超时和重试
  • 发送前验证输入
  • 生产环境API使用HTTPS

Response Handling

响应处理

  • Check status codes before parsing
  • Handle errors gracefully
  • Validate response schema
  • Log requests and responses for debugging
  • Implement exponential backoff for retries
  • 解析前检查状态码
  • 优雅地处理错误
  • 验证响应schema
  • 记录请求和响应以用于调试
  • 实现指数退避重试机制

Security Testing

安全测试

  • Test with invalid tokens
  • Test without authentication
  • Attempt SQL injection in parameters
  • Test XSS in input fields
  • Verify CORS settings
  • Test rate limiting
  • 使用无效令牌测试
  • 无认证情况下测试
  • 在参数中尝试SQL注入
  • 在输入字段中测试XSS
  • 验证CORS设置
  • 测试速率限制

Error Scenarios to Test

需测试的错误场景

  • Invalid authentication
  • Missing required fields
  • Invalid data types
  • Duplicate resources
  • Not found (404)
  • Server errors (500)
  • Rate limit exceeded (429)
  • Network timeouts
  • 无效认证
  • 缺少必填字段
  • 无效数据类型
  • 重复资源
  • 资源不存在(404)
  • 服务器错误(500)
  • 超出速率限制(429)
  • 网络超时

Common HTTP Status Codes

常见HTTP状态码

200 OK - Request successful
201 Created - Resource created
204 No Content - Success, no response body
400 Bad Request - Invalid request
401 Unauthorized - Missing/invalid authentication
403 Forbidden - Not allowed to access
404 Not Found - Resource doesn't exist
409 Conflict - Resource already exists
422 Unprocessable Entity - Validation failed
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Server error
502 Bad Gateway - Upstream server error
503 Service Unavailable - Server overloaded
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 - 服务器过载

Notes

注意事项

  • Always test in development/staging before production
  • Use environment variables for API URLs and tokens
  • Document all test cases and expected results
  • Automate testing in CI/CD pipeline
  • Monitor API performance and error rates
  • Keep Postman collections updated
  • Test edge cases and error scenarios
  • Validate both success and failure paths
  • Use proper authentication methods
  • Never commit API keys or tokens to version control
  • 始终先在开发/预发布环境测试,再到生产环境
  • 使用环境变量存储API地址和令牌
  • 记录所有测试用例和预期结果
  • 在CI/CD流水线中自动化测试
  • 监控API性能和错误率
  • 保持Postman集合更新
  • 测试边缘情况和错误场景
  • 验证成功和失败路径
  • 使用合适的认证方法
  • 切勿将API密钥或令牌提交到版本控制系统