api-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Testing
API测试
Expert knowledge for testing HTTP APIs with Supertest (TypeScript/JavaScript) and httpx/pytest (Python).
具备使用Supertest(TypeScript/JavaScript)和httpx/pytest(Python)进行HTTP API测试的专业知识。
Core Expertise
核心能力
API Testing Capabilities
- Request testing: Headers, query params, request bodies
- Response validation: Status codes, headers, JSON schemas
- Authentication: Bearer tokens, cookies, OAuth flows
- Error handling: 4xx/5xx responses, validation errors
- Integration: Database state, external services
- Performance: Response times, load testing basics
API测试能力
- 请求测试:请求头、查询参数、请求体
- 响应验证:状态码、响应头、JSON Schema
- 身份认证:Bearer令牌、Cookie、OAuth流程
- 错误处理:4xx/5xx响应、验证错误
- 集成测试:数据库状态、外部服务
- 性能测试:响应时间、基础负载测试
TypeScript/JavaScript (Supertest)
TypeScript/JavaScript(Supertest)
Installation
安装
bash
undefinedbash
undefinedUsing Bun
Using Bun
bun add -d supertest @types/supertest
bun add -d supertest @types/supertest
Using npm
Using npm
npm install -D supertest @types/supertest
undefinednpm install -D supertest @types/supertest
undefinedBasic Setup with Express
与Express的基础配置
typescript
// 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 })
})typescript
// 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: 'john@example.com' })
.expect(201)
expect(response.body).toMatchObject({
id: expect.any(Number),
name: 'John Doe',
email: 'john@example.com',
})
})
it('validates required fields', async () => {
const response = await request(app)
.post('/api/users')
.send({ name: 'John Doe' })
.expect(400)
expect(response.body.error).toBeDefined()
})
})typescript
// 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 })
})typescript
// 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: 'john@example.com' })
.expect(201)
expect(response.body).toMatchObject({
id: expect.any(Number),
name: 'John Doe',
email: 'john@example.com',
})
})
it('validates required fields', async () => {
const response = await request(app)
.post('/api/users')
.send({ name: 'John Doe' })
.expect(400)
expect(response.body.error).toBeDefined()
})
})Request Methods
请求方法
typescript
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: 'john@example.com' }).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: 'jane@example.com' }).expect(200)
// DELETE request
await request(app).delete('/api/users/1').expect(204)typescript
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: 'john@example.com' }).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: 'jane@example.com' }).expect(200)
// DELETE request
await request(app).delete('/api/users/1').expect(204)Headers and Query Parameters
请求头与查询参数
typescript
// 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)typescript
// 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)Response Assertions
响应断言
typescript
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: 'john@example.com',
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')
})
})typescript
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: 'john@example.com',
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)
Python(httpx + pytest)
Installation
安装
bash
undefinedbash
undefinedUsing uv
Using uv
uv add --dev httpx pytest-asyncio
uv add --dev httpx pytest-asyncio
Using pip
Using pip
pip install httpx pytest-asyncio
undefinedpip install httpx pytest-asyncio
undefinedBasic Setup with FastAPI
与FastAPI的基础配置
python
undefinedpython
undefinedmain.py
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": "john@example.com"}
```pythonfrom 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": "john@example.com"}
```pythontest_main.py
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": "john@example.com"}
)
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
For detailed examples including authentication testing, file uploads, cookie testing, database integration, schema validation, GraphQL testing, performance testing, best practices, and troubleshooting, see [REFERENCE.md](REFERENCE.md).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": "john@example.com"}
)
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测试、数据库集成、Schema验证、GraphQL测试、性能测试、最佳实践以及故障排查的详细示例,请查看[REFERENCE.md](REFERENCE.md)。Agentic Optimizations
智能优化命令
| Context | Command |
|---|---|
| Quick test (Bun) | |
| Quick test (pytest) | |
| Run single test file | |
| Verbose on failure | |
| 场景 | 命令 |
|---|---|
| 快速测试(Bun) | |
| 快速测试(pytest) | |
| 运行单个测试文件 | |
| 失败时显示详细信息 | |
See Also
相关链接
- - Unit testing framework
vitest-testing - - Python pytest patterns
python-testing - - E2E API testing
playwright-testing - - Test quality patterns
test-quality-analysis
- - 单元测试框架
vitest-testing - - Python pytest测试模式
python-testing - - 端到端API测试
playwright-testing - - 测试质量分析模式
test-quality-analysis
References
参考资料
- Supertest: https://github.com/ladjs/supertest
- httpx: https://www.python-httpx.org/
- FastAPI Testing: https://fastapi.tiangolo.com/tutorial/testing/
- Node.js Testing Best Practices: https://github.com/goldbergyoni/nodejs-testing-best-practices
- Supertest: https://github.com/ladjs/supertest
- httpx: https://www.python-httpx.org/
- FastAPI Testing: https://fastapi.tiangolo.com/tutorial/testing/
- Node.js Testing Best Practices: https://github.com/goldbergyoni/nodejs-testing-best-practices