api-testing · secondsky — скилл для Claude Code: тесты HTTP API
Скилл учит агента писать тесты HTTP API: Supertest в TypeScript, httpx и pytest в Python. Пригодится, когда нужно закрыть REST, GraphQL и проверку ошибок.
npx skills add secondsky/claude-skills --skill api-testing -a claude-codeЧто делает api-testing
Скилл даёт агенту готовые шаблоны тестов на двух стеках. В TypeScript это Supertest вместе с vitest: запросы через request(app), проверка статуса, тела ответа и заголовков. В Python — httpx и pytest-asyncio, плюс TestClient из FastAPI. Отдельные разделы про GraphQL-запросы с переменными, загрузку файлов через tmp_path и замер времени ответа.
Внутри — примеры на каждый метод: GET, POST с телом, PUT, DELETE. Есть блок про авторизацию: логин в beforeAll, сохранение токена и запрос к защищённому эндпоинту с заголовком Authorization. И проверки ошибок — 400 на невалидные поля, 404 на несуществующий id.
Скилл ничего не запускает сам: он подсказывает агенту, какой код писать. Поэтому тестовый фреймворк и зависимости должны быть в проекте заранее — Supertest ставится отдельно, для Python нужны httpx и pytest-asyncio. Если в проекте нет ни vitest, ни pytest, примеры придётся адаптировать под то, что уже есть.
Какие задачи решает
- написать тест на создание пользователя через POST
- проверить, что защищённый эндпоинт отдаёт 401 без токена
- протестировать GraphQL-запрос с переменными
- проверить формат сообщения об ошибке валидации
- загрузить файл в тесте и убедиться, что он принят
Примеры запросов агенту
- напиши тесты для эндпоинтов /api/users на Supertest
- добавь pytest-тест на логин и запрос к защищённому эндпоинту
- проверь GraphQL-запрос user с переменной id
Как установить api-testing
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill api-testing -a claude-code2Вручную: положить файлы
~/.claude/skills/api-testing/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/api-testing/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill api-testing -a codex2Вручную: положить файлы
.agents/skills/api-testing/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill api-testing -a cursor2Вручную: положить файлы
.cursor/skills/api-testing/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install secondsky/claude-skills api-testing2Вручную: положить файлы
.github/skills/api-testing/SKILL.md1Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill api-testing -a gemini-cli2Командой платформы
gemini skills install https://github.com/secondsky/claude-skills --path plugins/api-testing/skills/api-testingВручную: положить файлы
.devin/skills/api-testing/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add secondsky/claude-skills --skill api-testing -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о api-testing
Как установить api-testing в Claude?
Выполните npx skills add secondsky/claude-skills --skill api-testing -a claude-code. Файл скилла появится по пути ~/.claude/skills/api-testing/SKILL.md.
Что делает api-testing?
Даёт агенту шаблоны тестов HTTP API: Supertest для TypeScript, httpx и pytest для Python. Покрывает REST, GraphQL, авторизацию и обработку ошибок.
Нужно ли что-то доустанавливать?
Да. Для TypeScript-примеров нужен Supertest, для Python — httpx и pytest-asyncio. Скилл только подсказывает код, тестовый фреймворк в проекте должен быть свой.
Исходный текст
SKILL.md · MIT
---
name: api-testing
description: HTTP API testing for TypeScript (Supertest) and Python (httpx, pytest). Test REST APIs, GraphQL, request/response validation, authentication, and error handling.
allowed-tools: Bash, Read, Edit, Write, Grep, Glob, TodoWrite
license: MIT
---
# API Testing
Expert knowledge for testing HTTP APIs with Supertest (TypeScript/JavaScript) and httpx/pytest (Python).
## TypeScript/JavaScript (Supertest)
### Installation
```bash
# Using Bun
bun add -d supertest @types/supertest
# or: npm install -D supertest @types/supertest
```
### Basic Setup
```typescript
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',
})
})
it('validates required fields', async () => {
await request(app)
.post('/api/users')
.send({ name: 'John Doe' })
.expect(400)
})
})
```
### Request Methods
```typescript
// GET
await request(app).get('/api/users').expect(200)
// POST with body
await request(app)
.post('/api/users')
.send({ name: 'John' })
.expect(201)
// PUT
await request(app)
.put('/api/users/1')
.send({ name: 'Jane' })
.expect(200)
// DELETE
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')
.expect(200)
// Query parameters
await request(app)
.get('/api/users')
.query({ page: 1, limit: 10 })
.expect(200)
```
### Authentication Testing
```typescript
describe('Authentication', () => {
let authToken: string
beforeAll(async () => {
const response = await request(app)
.post('/api/auth/login')
.send({ email: '[email protected]', password: 'password123' })
.expect(200)
authToken = response.body.token
})
it('accesses protected endpoint', async () => {
await request(app)
.get('/api/protected')
.set('Authorization', `Bearer ${authToken}`)
.expect(200)
})
it('rejects without token', async () => {
await request(app).get('/api/protected').expect(401)
})
})
```
### Error Handling
```typescript
it('handles validation errors', async () => {
const response = await request(app)
.post('/api/users')
.send({ email: 'invalid-email' })
.expect(400)
expect(response.body).toMatchObject({
error: 'Validation failed',
details: expect.any(Array),
})
})
it('handles not found', async () => {
await request(app).get('/api/users/999999').expect(404)
})
```
## Python (httpx + pytest)
### Installation
```bash
uv add --dev httpx pytest-asyncio
```
### Basic Setup
```python
import pytest
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_not_found():
response = client.get("/api/users/999")
assert response.status_code == 404
```
### Fixtures
```python
@pytest.fixture
def auth_token(client):
response = client.post(
"/api/auth/login",
json={"email": "[email protected]", "password": "password123"}
)
return response.json()["token"]
def test_protected_endpoint(client, auth_token):
response = client.get(
"/api/protected",
headers={"Authorization": f"Bearer {auth_token}"}
)
assert response.status_code == 200
```
### File Upload
```python
def test_file_upload(client, tmp_path):
test_file = tmp_path / "test.txt"
test_file.write_text("test content")
with open(test_file, "rb") as f:
response = client.post(
"/api/upload",
files={"file": ("test.txt", f, "text/plain")}
)
assert response.status_code == 200
```
## GraphQL Testing
```typescript
it('queries GraphQL endpoint', async () => {
const query = `
query GetUser($id: ID!) {
user(id: $id) { id name email }
}
`
const response = await request(app)
.post('/graphql')
.send({ query, variables: { id: '1' } })
.expect(200)
expect(response.body.data.user).toMatchObject({
id: '1',
name: expect.any(String),
})
})
```
## Performance Testing
```typescript
it('responds within acceptable time', async () => {
const start = Date.now()
await request(app).get('/api/users').expect(200)
const duration = Date.now() - start
expect(duration).toBeLessThan(100) // 100ms threshold
})
```
## Best Practices
- Group related endpoints in `describe` blocks
- Reset database between tests
- Validate status codes first
- Check response structure
- Test error message format
- Mock external services
- Test both happy path and error cases
## See Also
- `vitest-testing` - Unit testing framework
- `playwright-testing` - E2E API testing
- `test-quality-analysis` - Test quality patterns
© secondsky · MIT · secondsky/claude-skills
Похожие скиллы
Всё по теме «Тесты и QA» →Сначала — api-testing от других авторов.