mcpField
A
automating-api-testing

automating-api-testing

github.com/jeremylongshore测试与质量2.9k68 次安装2 天前更新
代码仓库

关于 automating-api-testing

automating-api-testing 是用于生成和组织 REST 与 GraphQL API 测试的技能。它依据 API 规范覆盖端点行为、模式、身份验证、错误处理和测试覆盖率,并支持多种指定的测试工具。

主要功能

  1. 01生成 REST 与 GraphQL 测试
  2. 02分析 OpenAPI 和 GraphQL 模式
  3. 03检查身份验证与错误场景
  4. 04验证响应模式和标头
  5. 05测试 CRUD 生命周期及边缘情况
  6. 06报告端点测试覆盖率

适用场景

  1. 01根据 API 规范创建测试
  2. 02检查身份验证和错误响应
  3. 03验证 CRUD 行为与响应模式
  4. 04梳理 API 端点测试覆盖率

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jeremylongshore/tons-of-skills-marketplace --skill automating-api-testing

安装后在 Claude Code 中输入/automating-api-testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
example_graphql_schema.graphql
example_openapi.yaml
README.md
test_suite_template.js
references/
README.md
scripts/
generate_test_suite.py
README.md

详细介绍

API 测试自动化

概述

自动化测试 REST 和 GraphQL API 的完整 API 端点,包括请求生成、响应验证、架构合规性、身份验证流程和错误处理。支持 Supertest(Node.js)、REST-assured(Java)、httpx/pytest(Python)、Postman/Newman 集合,以及用于消费者驱动契约测试的 Pact。

前提条件

  • 已安装 API 测试库(Supertest、REST-assured、httpx 或 Postman/Newman)
  • API 规范文件(OpenAPI/Swagger YAML/JSON 或 GraphQL SDL)
  • 目标 API 在测试环境中运行,且已填充种子数据
  • 受保护端点所需的身份验证凭据或 API 密钥
  • JSON Schema 验证器(Ajv、jsonschema 或框架内置断言)

说明

  1. 阅读 API 规范并提取所有端点:
    • 解析 OpenAPI 规范,列出每个路径、HTTP 方法、请求架构和响应架构。
    • 对于 GraphQL API,内省架构以列出查询、变更和订阅。
    • 记录每个端点的身份验证要求(API 密钥、Bearer 令牌、OAuth 或无)。
  2. 为每个端点生成测试用例:
    • 成功用例:发送符合架构的有效请求,并断言响应为 200/201。
    • 验证错误:发送缺少必填字段、类型错误或值超出范围的请求;断言响应为 400。
    • 身份验证:使用有效、过期和缺失的凭据进行测试;分别断言响应为 200、401 和 403。
    • 未找到:请求不存在的资源;断言响应为 404。
    • 幂等性:两次发送相同的 PUT/DELETE 请求,并验证行为一致。
  3. 根据架构验证响应结构:
    • 断言响应 Content-Type 与预期相符(application/json 等)。
    • 使用 JSON Schema 验证,根据 OpenAPI 响应架构验证响应正文。
    • 检查响应标头(Cache-Control、Rate-Limit 标头、CORS 标头)。
    • 验证分页元数据(总数、页码、下一页/上一页链接)。
  4. 测试资源端点的 CRUD 生命周期:
    • 创建资源(POST)并捕获 ID。
    • 读取该资源(GET),并验证所有字段是否匹配。
    • 更新该资源(PUT/PATCH),并验证更改是否已保存。
    • 删除该资源(DELETE),并验证后续 GET 是否返回 404。
  5. 测试错误处理和边界情况:
    • 发送超大负载,并验证是否返回 413 或进行优雅拒绝。
    • 发送不支持的 Content-Type 请求,并验证是否返回 415。
    • 通过快速连续发送请求来测试速率限制。
    • 验证错误响应格式是否一致(标准错误架构)。
  6. 对于 GraphQL API,专门测试:
    • 有效查询是否返回预期的数据结构。
    • 无效查询是否返回描述性错误消息。
    • 查询深度限制是否能防止滥用深度嵌套的查询。
    • 变更输入验证是否符合架构约束。
  7. 生成测试覆盖率报告,将端点映射到测试用例。

输出

  • 按资源整理在 tests/api/ 中的 API 测试文件
  • 用于 API 文档的请求/响应示例
  • 每个端点的架构合规性报告
  • 端点覆盖矩阵,显示已测试和未测试的端点及方法
  • 在预发布环境中运行 API 测试的 CI 流水线步骤

错误处理

错误原因解决方案
连接被拒绝API 服务未运行或基础 URL 错误在测试套件启动前通过健康检查确认服务正常运行;检查 BASE_URL 配置
所有请求均返回 401身份验证令牌已过期或配置错误在测试设置中刷新令牌;确认 Authorization 标头格式;检查令牌范围
架构验证意外失败API 响应包含规范中未定义的额外字段更新 OpenAPI 规范以包含新字段;如果额外字段符合预期,则使用 additionalProperties: true
测试数据冲突其他测试修改或删除了该资源为每项测试使用唯一的测试数据;在 beforeEach 中创建资源;避免共享固定数据
测试运行期间触发速率限制短时间内发送了过多请求在请求之间增加延迟,或使用限制更高的已认证会话;串行运行测试

示例

Supertest REST API 测试套件:

import request from 'supertest';
import { app } from '../src/app';

describe('GET /api/products', () => {
  it('returns a paginated product list', async () => {
    const res = await request(app)
      .get('/api/products?page=1&limit=10')
      .set('Authorization', `Bearer ${token}`)
      .expect(200)  # HTTP 200 OK
      .expect('Content-Type', /json/);

    expect(res.body.data).toBeInstanceOf(Array);
    expect(res.body.data.length).toBeLessThanOrEqual(10);
    expect(res.body.meta).toMatchObject({ page: 1, limit: 10 });
  });

  it('returns 401 without authentication', async () => {  # HTTP 401 Unauthorized
    await request(app).get('/api/products').expect(401);  # HTTP 401 Unauthorized
  });
});

describe('POST /api/products', () => {
  it('creates a product with valid data', async () => {
    const res = await request(app)
      .post('/api/products')
      .set('Authorization', `Bearer ${token}`)
      .send({ name: 'Widget', price: 9.99, category: 'tools' })
      .expect(201);  # HTTP 201 Created

    expect(res.body).toMatchObject({ name: 'Widget', price: 9.99 });
    expect(res.body.id).toBeDefined();
  });

  it('returns 400 for missing required fields', async () => {  # HTTP 400 Bad Request
    await request(app)
      .post('/api/products')
      .set('Authorization', `Bearer ${token}`)
      .send({ name: 'Widget' }) // missing price
      .expect(400);  # HTTP 400 Bad Request
  });
});

GraphQL API 测试:

it('fetches user by ID', async () => {
  const query = `query { user(id: "1") { id name email } }`;
  const res = await request(app)
    .post('/graphql')
    .send({ query })
    .expect(200);  # HTTP 200 OK

  expect(res.body.data.user).toMatchObject({ id: '1', name: 'Alice' });
  expect(res.body.errors).toBeUndefined();
});

资源

评论

支持 Markdown