19 KiB
Контекст проекта
Мы разрабатываем стартап/проект для автоматизированного end-to-end тестирования пользовательских API через GitHub Actions.
Главная идея
Продукт должен позволять разработчику проверить, что его backend-приложение действительно работает целиком с точки зрения пользователя.
Это НЕ API monitoring и НЕ сервис, который постоянно проверяет API.
Тест запускается один раз в рамках CI/CD pipeline.
Основной сценарий:
GitHub Actions Job
│
├── Checkout repository
│
├── Build application
│
├── Start application
│
├── Wait until application is ready
│
├── Run API E2E tests
│
├── Generate report
│
└── Cleanup
Например:
POST /register
↓
POST /login
↓
GET /profile
↓
POST /posts
↓
GET /posts/{id}
↓
DELETE /posts/{id}
Если любой шаг ломается, GitHub Actions Job должен завершиться с ошибкой.
Главная ценность продукта
Продукт должен проверять не отдельные endpoints, а полноценные пользовательские сценарии.
Например:
Register user
↓
получить user_id
↓
Login
↓
получить JWT
↓
Get profile с JWT
↓
Create post
↓
получить post_id
↓
Get post
↓
Delete post
Данные между запросами должны автоматически передаваться.
Пример:
login.response.token
↓
Authorization: Bearer {{token}}
create.response.id
↓
GET /posts/{{post_id}}
Важное отличие от обычного API monitoring
Не нужно постоянно проверять:
GET /health
GET /health
GET /health
Нас интересует одноразовая проверка:
"Я только что поднял приложение. Может ли реальный пользователь пройти через основной сценарий и работает ли API целиком?"
Основной execution environment
Основной execution environment — GitHub Actions.
Очень важно:
Тестируемое приложение должно запускаться в рамках того же GitHub Actions Job, в котором выполняется API E2E test.
Например:
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start application
run: docker compose -f docker-compose.test.yml up -d
- name: API E2E
uses: our-org/api-e2e@v1
with:
spec: tests/api.yaml
base-url: http://localhost:8080
- name: Cleanup
if: always()
run: docker compose -f docker-compose.test.yml down -v
В будущем желательно, чтобы сам Action мог запускать Docker Compose и выполнять cleanup автоматически.
Требование к Docker
Основной вариант для MVP:
Docker
Docker Compose
Типичное приложение:
docker-compose.test.yml
api
postgres
redis
etc.
Продукт должен уметь:
- запустить приложение;
- дождаться readiness;
- проверить healthcheck;
- выполнить тесты;
- собрать результаты;
- удалить контейнеры;
- выполнить cleanup даже при падении тестов.
API Test Engine
Главное ядро проекта — собственный API Test Engine.
Он должен поддерживать:
GET
POST
PUT
PATCH
DELETE
HEAD
OPTIONS
Каждый request должен иметь:
Method
URL
Headers
Query parameters
Body
Timeout
Variables
Assertions
Extraction
Variables
Нужны обычные переменные:
variables:
email: test@example.com
password: Test123!
Использование:
url: /api/users/{{user_id}}
Dynamic variables
Нужна генерация тестовых данных:
{{random.uuid}}
{{random.email}}
{{random.username}}
{{random.string}}
{{random.number}}
{{timestamp}}
Это необходимо для сценариев регистрации и создания ресурсов.
Extraction
Один request должен уметь извлекать данные из response и передавать их следующим request.
Например:
- name: Login
request:
method: POST
url: /api/login
extract:
token: "$.token"
Следующий request:
- name: Profile
request:
method: GET
url: /api/profile
headers:
Authorization: "Bearer {{token}}"
Для JSON желательно использовать JSONPath или совместимый механизм.
Assertions
Минимально необходимы:
HTTP status
JSON field exists
JSON value
Header
Response time
Regex
Contains
Equals
Not equals
Exists
Например:
expect:
status: 200
json:
user.id:
exists: true
user.email:
equals: "{{email}}"
OpenAPI
Продукт обязательно должен поддерживать:
OpenAPI 3.0
OpenAPI 3.1
YAML
JSON
OpenAPI должен использоваться для:
- импорта API;
- обнаружения endpoints;
- определения HTTP methods;
- определения parameters;
- определения request body;
- определения response schemas;
- генерации базовых тестов;
- schema validation.
Например:
OpenAPI
↓
Parser
↓
Internal Test Model
↓
API Test Engine
Postman
Продукт должен поддерживать импорт:
Postman Collection v2
Postman Collection v2.1
Нужно поддержать:
- requests;
- methods;
- URLs;
- headers;
- query parameters;
- body;
- variables;
- environments;
- authentication;
- request chains;
- basic assertions;
- extracted variables.
Очень важно:
OpenAPI и Postman не должны напрямую использоваться Test Engine.
Оба формата должны преобразовываться во внутреннюю модель.
Postman ────────┐
↓
Internal Test Model
↑
OpenAPI ────────┘
↓
Test Engine
Это позволит позже добавлять другие форматы.
Authentication
Минимально:
None
Basic Auth
Bearer Token
API Key
OAuth 2.0
Особенно важен сценарий:
POST /login
↓
extract JWT
↓
Bearer {{token}}
↓
GET /profile
Reporting
После теста должны создаваться:
Console report
JUnit XML
JSON
HTML
GitHub Step Summary
Пример:
API E2E Tests
✓ Register 184ms
✓ Login 92ms
✓ Profile 61ms
✓ Create post 142ms
✗ Delete post 83ms
5 / 6 passed
FAILED:
Delete post
Expected: 204
Received: 500
GitHub Actions должен получать корректный exit code:
0 = success
1 = failure
Также нужны GitHub annotations:
::error
::warning
::notice
::group
Local CLI
Хотя основное выполнение происходит через GitHub Actions, Test Engine должен работать локально.
Например:
api-e2e run tests/api.yaml
или:
api-e2e run \
--spec tests/api.yaml \
--base-url http://localhost:8080
Также нужны:
api-e2e validate
api-e2e import
api-e2e report
Локальный запуск нужен для debugging.
Один и тот же тест должен работать:
Local
↓
api-e2e CLI
CI
↓
GitHub Action
Будущая SaaS-часть
После создания рабочего Test Engine можно сделать веб-платформу.
Frontend:
Dashboard
Projects
Test scenarios
Scenario editor
Request editor
Assertions editor
Run history
Test results
Logs
Reports
GitHub integration
Backend:
Users
Projects
Repositories
Test scenarios
Test runs
Results
GitHub integrations
Backend НЕ должен выполнять пользовательские API-тесты напрямую.
Основное выполнение должно происходить в GitHub Actions.
GitHub App
В дальнейшем желательно сделать полноценный GitHub App вместо ручного PAT.
Пользователь:
Connect GitHub
↓
Install GitHub App
↓
Select repository
↓
Select tests
GitHub integration должна позволять запускать тесты:
Pull Request
Push
Manual
Release
Schedule
Рекомендуемый стек
Мы остановились на TypeScript.
Test Engine
TypeScript
Node.js
CLI
TypeScript
Commander или аналог
GitHub Action
TypeScript
Node.js
Backend
TypeScript
Node.js
Fastify
Database
PostgreSQL
ORM
Drizzle или Prisma
Frontend
Next.js
React
TypeScript
Tailwind
Infrastructure
Docker
Docker Compose
GitHub Actions
Предполагаемая архитектура
GitHub Actions
│
▼
┌─────────────────┐
│ API E2E CLI │
│ / Action │
└────────┬────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
OpenAPI Parser Postman Parser Config
│ │ │
└──────────────┼──────────────┘
▼
Internal Test Model
│
▼
Test Engine
│
┌──────────────┼──────────────┐
▼ ▼ ▼
HTTP Variables Assertions
│ │ │
└──────────────┼──────────────┘
▼
Reports
Структура репозитория
Предполагаемая структура:
api-e2e/
│
├── packages/
│ ├── engine/
│ │ ├── http/
│ │ ├── assertions/
│ │ ├── variables/
│ │ ├── extraction/
│ │ ├── runner/
│ │ └── reports/
│ │
│ ├── openapi/
│ │ └── parser/
│ │
│ ├── postman/
│ │ └── parser/
│ │
│ ├── config/
│ └── cli/
│
├── action/
│ ├── action.yml
│ └── src/
│
├── backend/
├── frontend/
│
├── examples/
│ ├── basic/
│ ├── docker-compose/
│ ├── openapi/
│ └── postman/
│
├── tests/
│
├── docker-compose.yml
├── package.json
└── README.md
Очередность разработки
Очень важно: не начинать сразу с SaaS/frontend/backend.
Разработка должна идти в следующем порядке.
Phase 1 — Test Engine
Сначала сделать полностью автономный CLI.
Цель:
api-e2e run tests/api.yaml
Он должен:
Load config
↓
Execute requests
↓
Pass variables
↓
Extract values
↓
Run assertions
↓
Return result
↓
Exit code
После этой фазы можно локально протестировать полноценный E2E workflow.
Phase 2 — Variables + Extraction + Assertions
Добавить:
- static variables;
- environment variables;
- random data;
- JSON extraction;
- JSONPath;
- status assertions;
- JSON assertions;
- header assertions;
- response-time assertions;
- regex;
- contains;
- equals;
- exists.
Phase 3 — Docker
Добавить:
- Docker Compose;
- startup;
- readiness;
- healthcheck;
- timeout;
- logs;
- cleanup;
- cleanup on failure.
Цель:
api-e2e run \
--compose docker-compose.test.yml \
--spec tests/api.yaml
Должно происходить:
Start containers
↓
Wait for API
↓
Run tests
↓
Generate report
↓
Cleanup
Phase 4 — GitHub Action
После того как CLI работает локально:
- action.yml;
- inputs;
- outputs;
- exit codes;
- GitHub annotations;
- GitHub Step Summary;
- JUnit;
- artifacts.
Цель:
- uses: our-org/api-e2e@v1
with:
spec: tests/api.yaml
compose: docker-compose.test.yml
Phase 5 — OpenAPI
Добавить:
- OpenAPI 3.0;
- OpenAPI 3.1;
- YAML;
- JSON;
- endpoint discovery;
- request generation;
- response schema validation;
- authentication;
- test generation.
Phase 6 — Postman
Добавить:
- Collection v2;
- Collection v2.1;
- environments;
- variables;
- headers;
- authentication;
- body;
- assertions;
- extracted variables;
- chained requests.
Phase 7 — Web UI
Только после рабочего CLI и GitHub Action.
Добавить:
- authentication;
- projects;
- GitHub integration;
- test scenario editor;
- request editor;
- assertions editor;
- run history;
- results;
- logs;
- reports.
Phase 8 — GitHub App
Добавить:
- GitHub App;
- repository selection;
- workflow integration;
- permissions;
- webhooks;
- automatic PR integration.
Phase 9 — SaaS
После появления рабочего продукта:
- accounts;
- teams;
- projects;
- usage limits;
- billing;
- plans;
- cloud storage;
- test history.
MVP
Первый MVP должен содержать только:
- GitHub Action;
- CLI;
- YAML test specification;
- HTTP requests;
- variables;
- extraction;
- assertions;
- Docker Compose;
- startup;
- readiness;
- cleanup;
- JUnit;
- GitHub Summary;
- OpenAPI import;
- Postman import.
Не делать в MVP:
- API monitoring;
- browser testing;
- load testing;
- Kubernetes;
- собственные CI runners;
- AI;
- десятки интеграций;
- сложную SaaS-платформу.
Безопасность
Это критически важная часть.
Тесты могут содержать:
API keys
Passwords
JWT
Cookies
Database credentials
Production secrets
Поэтому:
- secrets нельзя писать в logs;
- Authorization headers должны маскироваться;
- passwords нельзя сохранять;
- secrets должны передаваться через GitHub Secrets;
- response body не должен отправляться на наш сервер без явного разрешения;
- необходимо ограничивать размеры response;
- необходимо ограничивать timeout;
- необходимо валидировать URLs;
- необходимо предотвращать SSRF;
- нельзя выполнять произвольные shell-команды из пользовательской конфигурации;
- выполнение тестов должно происходить в изолированном GitHub Actions environment.
Особенно важно:
Backend SaaS не должен напрямую выполнять произвольные HTTP-запросы пользователей.
Главный принцип разработки
Не пытаться сразу создать огромную платформу.
Сначала должно работать:
Docker Compose
↓
Application
↓
API E2E Engine
↓
Assertions
↓
Report
↓
Cleanup
Потом:
CLI
↓
GitHub Action
Потом:
OpenAPI
+
Postman
И только потом:
Frontend
+
Backend
+
GitHub App
+
SaaS
Конечная концепция продукта
Продукт должен отвечать на простой вопрос:
«Если я только что поднял своё приложение, может ли реальный пользователь пройти через основной API-сценарий от начала до конца?»
Пример:
Application started
↓
Healthcheck
↓
Register
↓
Login
↓
Get profile
↓
Create resource
↓
Get resource
↓
Update resource
↓
Delete resource
↓
PASS
В идеале пользователь должен иметь возможность взять существующий:
OpenAPI
или:
Postman Collection
и практически сразу получить готовый E2E-тест, который можно запускать локально и в GitHub Actions.
Главная конкурентная идея продукта:
Не заменять Postman или OpenAPI, а превращать существующие API-описания в воспроизводимые E2E CI-тесты, которые проверяют реальный пользовательский сценарий на только что запущенном приложении.