mcpField
A
api-testing

api-testing

github.com/laurigates测试与质量59106 次安装今天更新
代码仓库

关于 api-testing

面向开发者的 HTTP API 测试技能,涵盖 TypeScript/JavaScript 与 Python 示例,可检查请求响应、认证、错误和集成状态。

主要功能

  1. 01Supertest 端点测试
  2. 02httpx 与 pytest 测试
  3. 03请求和响应校验
  4. 04认证与错误检查
  5. 05数据库及服务集成

适用场景

  1. 01测试 Express 或 Fastify 端点
  2. 02测试 Python REST 或 GraphQL API
  3. 03检查认证流程和错误响应

安装

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

$npx skills add https://github.com/laurigates/claude-plugins --skill api-testing

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

附带文件REFERENCE.md

详细介绍

API 测试

使用 Supertest(TypeScript/JavaScript)和 httpx/pytest(Python)测试 HTTP API 的专业知识。

何时使用此技能

在以下情况下使用此技能……在以下情况下改用 configure-plugin:configure-api-tests……
为 Express/Fastify 应用编写 Supertest 端点测试搭建 Pact 消费者/提供者契约测试基础设施
为 Python REST/GraphQL API 编写 httpx + pytest 测试验证 OpenAPI 规范,或将架构(Zod/AJV)检查接入 CI
在测试代码中验证请求/响应结构、状态码和身份验证流程审计或搭建项目的 API 契约测试工具
在功能测试中断言错误处理(4xx/5xx)和集成状态在 CI 中添加破坏性变更检测工作流

核心专业知识

API 测试能力

  • 请求测试:标头、查询参数、请求正文
  • 响应验证:状态码、标头、JSON 架构
  • 身份验证:Bearer 令牌、Cookie、OAuth 流程
  • 错误处理:4xx/5xx 响应、验证错误
  • 集成:数据库状态、外部服务
  • 性能:响应时间、负载测试基础知识

TypeScript/JavaScript(Supertest)

安装
# Using Bun
bun add -d supertest @types/supertest

# Using npm
npm install -D supertest @types/supertest
使用 Express 进行基础设置
// app.ts
import express from 'express'

export const app = express()
app.use(express.json())

app.get('/api/health', (req, res) => {
  res.json({ status: 'ok' })
})

app.post('/api/users', (req, res) => {
  const { name, email } = req.body
  if (!name || !email) {
    return res.status(400).json({ error: 'Missing required fields' })
  }
  res.status(201).json({ id: 1, name, email })
})
// app.test.ts
import { describe, it, expect } from 'vitest'
import request from 'supertest'
import { app } from './app'

describe('API Tests', () => {
  it('returns health status', async () => {
    const response = await request(app)
      .get('/api/health')
      .expect(200)

    expect(response.body).toEqual({ status: 'ok' })
  })

  it('creates a user', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({ name: 'John Doe', email: '[email protected]' })
      .expect(201)

    expect(response.body).toMatchObject({
      id: expect.any(Number),
      name: 'John Doe',
      email: '[email protected]',
    })
  })

  it('validates required fields', async () => {
    const response = await request(app)
      .post('/api/users')
      .send({ name: 'John Doe' })
      .expect(400)

    expect(response.body.error).toBeDefined()
  })
})
请求方法
import request from 'supertest'
import { app } from './app'

// GET request
await request(app).get('/api/users').expect(200)

// POST request with body
await request(app).post('/api/users')
  .send({ name: 'John', email: '[email protected]' }).expect(201)

// PUT request
await request(app).put('/api/users/1')
  .send({ name: 'Jane' }).expect(200)

// PATCH request
await request(app).patch('/api/users/1')
  .send({ email: '[email protected]' }).expect(200)

// DELETE request
await request(app).delete('/api/users/1').expect(204)
标头和查询参数
// Set headers
await request(app)
  .get('/api/protected')
  .set('Authorization', 'Bearer token123')
  .set('Content-Type', 'application/json')
  .expect(200)

// Query parameters
await request(app)
  .get('/api/users')
  .query({ page: 1, limit: 10 })
  .expect(200)
响应断言
describe('Response validation', () => {
  it('validates status code', async () => {
    await request(app).get('/api/users').expect(200)
  })

  it('validates headers', async () => {
    await request(app).get('/api/users')
      .expect('Content-Type', /json/).expect(200)
  })

  it('validates response body', async () => {
    const response = await request(app).get('/api/users/1').expect(200)
    expect(response.body).toEqual({
      id: 1,
      name: 'John Doe',
      email: '[email protected]',
      createdAt: expect.any(String),
    })
  })

  it('validates array responses', async () => {
    const response = await request(app).get('/api/users').expect(200)
    expect(response.body).toBeInstanceOf(Array)
    expect(response.body).toHaveLength(5)
    expect(response.body[0]).toHaveProperty('id')
  })
})

Python(httpx + pytest)

安装
# Using uv
uv add --dev httpx pytest-asyncio

# Using pip
pip install httpx pytest-asyncio
使用 FastAPI 进行基础设置
# main.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    name: str
    email: str

@app.get("/api/health")
def health_check():
    return {"status": "ok"}

@app.post("/api/users", status_code=201)
def create_user(user: User):
    return {"id": 1, "name": user.name, "email": user.email}

@app.get("/api/users/{user_id}")
def get_user(user_id: int):
    if user_id == 999:
        raise HTTPException(status_code=404, detail="User not found")
    return {"id": user_id, "name": "John Doe", "email": "[email protected]"}
# test_main.py
from fastapi.testclient import TestClient
from main import app

client = TestClient(app)

def test_health_check():
    response = client.get("/api/health")
    assert response.status_code == 200
    assert response.json() == {"status": "ok"}

def test_create_user():
    response = client.post(
        "/api/users",
        json={"name": "John Doe", "email": "[email protected]"}
    )
    assert response.status_code == 201
    data = response.json()
    assert data["name"] == "John Doe"
    assert "id" in data

def test_validation_error():
    response = client.post("/api/users", json={"name": "John"})
    assert response.status_code == 422  # FastAPI validation error

def test_not_found():
    response = client.get("/api/users/999")
    assert response.status_code == 404

有关身份验证测试、文件上传、Cookie 测试、数据库集成、架构验证、GraphQL 测试、性能测试、最佳实践和故障排除的详细示例,请参阅 REFERENCE.md。

Agentic 优化

场景命令
快速测试(Bun)bun test --dots --bail=1 api
快速测试(pytest)pytest -x --tb=short tests/api/
运行单个测试文件bun test --dots path/to/test.ts
失败时显示详细信息bun test --bail=1 api

另请参阅

  • vitest-testing - 单元测试框架
  • python-testing - Python pytest 模式
  • playwright-testing - E2E API 测试
  • test-quality-analysis - 测试质量模式

参考资料

评论

支持 Markdown