docs: Added documentation for models and methods

This commit is contained in:
Black_Raven committed 2026-08-24 17:03:31 +03:00
1 parent c26c60f679
commit 2e7c69c5af
1 file changed
+730
+730
View File
@@ -0,0 +1,730 @@
# API Checker
Инструмент для автоматизированного end-to-end тестирования API через GitHub Actions.
---
## Содержание
- [Архитектура](#архитектура)
- [Models](#models)
- [AuthModel](#authmodel)
- [RequestModel](#requestmodel)
- [ExtractModel](#extractmodel)
- [AssertModel](#assertmodel)
- [StepModel](#stepmodel)
- [TestModel](#testmodel)
- [Context](#context)
- [Response](#response)
- [Executor](#executor)
- [Extractor](#extractor)
- [Validator](#validator)
- [StepResult](#stepresult)
- [TestResult](#testresult)
- [TestRunner](#testrunner)
- [YAML Readers](#yaml-readers)
- [ParseError](#parseerror)
- [BaseReader](#basereader)
- [YamlReader](#yamlreader)
- [PostmanReader](#postmanreader)
- [OpenAPIReader](#openapireader)
- [get_reader](#get_reader)
- [Примеры использования](#примеры-использования)
---
## Архитектура
```
YAML/OpenAPI/Postman → Parser → TestModel → Context → Runner → TestResult
```
---
## Models
### AuthModel
**Файл:** `models/itm.py`
Модель аутентификации.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `type` | `str` | `"none"` | Тип аутентификации: `none`, `basic`, `bearer`, `api_key`, `oauth2` |
| `credentials` | `dict[str, str]` | `{}` | Данные для аутентификации |
**Когда использовать:** Когда API требует аутентификацию. Передаётся в `TestModel.auth`.
---
### RequestModel
**Файл:** `models/itm.py`
Модель HTTP запроса.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `method` | `str` | `"GET"` | HTTP метод: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS` |
| `path` | `str` | `"/"` | Путь URL (поддерживает `{{variable}}`) |
| `headers` | `dict[str, str]` | `{}` | HTTP заголовки |
| `query` | `dict[str, str]` | `{}` | Query параметры |
| `body` | `dict \| str \| None` | `None` | Тело запроса |
| `body_type` | `str` | `"json"` | Тип тела: `json`, `form`, `raw` |
| `timeout` | `int` | `30` | Таймаут в секундах |
**Когда использовать:** Определяет что отправить серверу. Передаётся в `StepModel.request`.
---
### ExtractModel
**Файл:** `models/itm.py`
Модель извлечения данных из ответа.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `name` | `str` | — | Имя переменной (обязательное) |
| `json_path` | `str` | — | JSON-путь к значению: `$.token`, `$.user.id` (обязательное) |
| `source` | `str` | `"body"` | Источник: `body`, `header`, `status` |
**Когда использовать:** Когда нужно сохранить данные из ответа для использования в следующих запросах. Передаётся в `StepModel.extract`.
---
### AssertModel
**Файл:** `models/itm.py`
Модель проверки ответа.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `type` | `str` | — | Тип проверки: `status`, `json`, `header` (обязательное) |
| `path` | `str \| None` | `None` | JSON-путь к полю для проверки |
| `operator` | `str` | `"equals"` | Оператор: `equals`, `exists`, `gt`, `lt`, `contains`, `matches` |
| `value` | `Any` | `None` | Ожидаемое значение |
**Когда использовать:** Когда нужно проверить что ответ соответствует ожиданиям. Передаётся в `StepModel.assert_`.
---
### StepModel
**Файл:** `models/itm.py`
Модель одного шага теста.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `name` | `str` | — | Название шага (обязательное) |
| `request` | `RequestModel` | — | HTTP запрос (обязательное) |
| `extract` | `list[ExtractModel]` | `[]` | Извлечение данных |
| `assert_` | `list[AssertModel]` | `[]` | Проверки |
**Когда использовать:** Один логический шаг теста (например, "Залогиниться"). Передаётся в `TestModel.steps`.
---
### TestModel
**Файл:** `models/itm.py`
Основная модель теста. Содержит всю конфигурацию.
| Поле | Тип | По умолчанию | Описание |
|------|-----|--------------|----------|
| `name` | `str` | `"Unnamed Test"` | Название теста |
| `base_url` | `str` | `""` | Базовый URL API |
| `variables` | `dict[str, str]` | `{}` | Статические переменные |
| `auth` | `AuthModel \| None` | `None` | Аутентификация |
| `steps` | `list[StepModel]` | `[]` | Шаги теста |
**Когда использовать:** Главная входная точка. Создаётся парсерами или вручную.
---
### Context
**Файл:** `models/context.py`
Контекст выполнения. Хранит состояние во время запуска теста.
| Поле | Тип | Описание |
|------|-----|----------|
| `config` | `TestModel` | Оригинальная конфигурация теста |
| `variables` | `dict[str, str]` | Статические переменные из config |
| `extracted` | `dict[str, Any]` | Извлечённые данные из ответов |
**Методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `__init__(config)` | `TestModel` | — | Создаёт контекст из конфигурации |
| `resolve(template)` | `str` | `str` | Заменяет `{{var}}` на значение из variables или extracted |
| `set_extracted(name, value)` | `str, Any` | — | Сохраняет извлечённое значение |
**Когда использовать:** Передаётся всем компонентам (Executor, Extractor, TestRunner) для доступа к данным.
**Пример:**
```python
context = Context(TestModel(variables={"email": "test@x.com"}))
context.set_extracted("token", "abc123")
context.resolve("{{email}}") # "test@x.com"
context.resolve("Bearer {{token}}") # "Bearer abc123"
```
---
### Response
**Файл:** `models/executor.py`
Модель HTTP ответа.
| Поле | Тип | Описание |
|------|-----|----------|
| `status` | `int` | HTTP статус-код (200, 404, ...) |
| `body` | `dict` | Тело ответа (JSON) |
| `headers` | `dict` | Заголовки ответа |
**Когда использовать:** Создаётся Executor после выполнения запроса. Передаётся в Extractor и Validator.
---
### Executor
**Файл:** `models/executor.py`
Выполняет HTTP запросы.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `__init__(context)` | `Context` | — | Создаёт executor с контекстом |
| `_resolve_url(request)` | `RequestModel` | `str` | Разрешает URL с переменными |
| `execute(request)` | `RequestModel` | `Response` | Выполняет HTTP запрос |
**Когда использовать:** Отправляет запросы к API. Используется TestRunner.
**Пример:**
```python
context = Context(model)
executor = Executor(context)
response = executor.execute(RequestModel(method="GET", path="/api/users"))
print(response.status) # 200
```
---
### Extractor
**Файл:** `models/extractor.py`
Извлекает данные из HTTP ответов.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `__init__(context)` | `Context` | — | Создаёт extractor с контекстом |
| `extract(configs, response)` | `list[ExtractModel], Response` | — | Извлекает данные в context.extracted |
**Внутренние методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `_get_value(response, config)` | `Response, ExtractModel` | `Any` | Получает значение из ответа |
| `_json_path(data, path)` | `dict, str` | `Any` | Извлекает значение по JSON-пути |
**Когда использовать:** Когда нужно сохранить данные из ответа (токен, ID, ...) для использования в следующих шагах.
**Пример:**
```python
extractor = Extractor(context)
response = Response(status=200, body={"token": "abc123"}, headers={})
extractor.extract([ExtractModel(name="token", json_path="$.token")], response)
print(context.extracted["token"]) # "abc123"
```
---
### Validator
**Файл:** `models/validator.py`
Проверяет HTTP ответы.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `validate(asserts, response)` | `list[AssertModel], Response` | `bool` | Все ли проверки прошли |
**Внутренние методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `_check(assertion, response)` | `AssertModel, Response` | `bool` | Проверяет одно утверждение |
**Когда использовать:** Проверяет что ответ соответствует ожиданиям. Используется TestRunner.
**Пример:**
```python
validator = Validator()
response = Response(status=200, body={}, headers={})
asserts = [AssertModel(type="status", value=200)]
print(validator.validate(asserts, response)) # True
```
---
### StepResult
**Файл:** `models/runner.py`
Результат выполнения одного шага.
| Поле | Тип | Описание |
|------|-----|----------|
| `name` | `str` | Название шага |
| `passed` | `bool` | Прошёл ли шаг |
| `response` | `Response` | HTTP ответ |
**Когда использовать:** Создаётся TestRunner после выполнения шага. Возвращается в TestResult.
---
### TestResult
**Файл:** `models/runner.py`
Результат выполнения всего теста.
| Поле | Тип | Описание |
|------|-----|----------|
| `steps` | `list[StepResult]` | Результаты всех шагов |
**Свойства:**
| Свойство | Тип | Описание |
|----------|-----|----------|
| `passed` | `bool` | True если все шаги прошли |
**Когда использовать:** Возвращается TestRunner.run(). Используется для вывода результатов.
---
### TestRunner
**Файл:** `models/runner.py`
Оркестратор выполнения теста.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `__init__(context)` | `Context` | — | Создаёт runner с контекстом |
| `run()` | — | `TestResult` | Запускает все шаги теста |
**Когда использовать:** Главная точка входа для запуска теста.
**Пример:**
```python
context = Context(model)
runner = TestRunner(context)
result = runner.run()
print(result.passed) # True/False
for step in result.steps:
print(f"{step.name}: {'OK' if step.passed else 'FAIL'}")
```
---
## YAML Readers
### ParseError
**Файл:** `yamlreaders/base.py`
Исключение при ошибке парсинга.
| Поле | Тип | Описание |
|------|-----|----------|
| `line` | `int \| None` | Номер строки с ошибкой |
**Когда использовать:** Ловить при парсинге невалидных YAML файлов.
---
### BaseReader
**Файл:** `yamlreaders/base.py`
Абстрактный базовый класс для всех парсеров.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `validate(source)` | `str \| Path` | `bool` | Проверяет валидность файла |
| `parse(source)` | `str \| Path` | `TestModel` | Конвертирует файл в TestModel |
| `load_yaml(source)` | `str \| Path` | `dict` | Загружает YAML файл |
**Исключения:**
- `FileNotFoundError` — файл не найден
- `ParseError` — ошибка парсинга
**Когда использовать:** Не используется напрямую. Используйте наследников (YamlReader, PostmanReader, OpenAPIReader).
---
### YamlReader
**Файл:** `yamlreaders/yaml_reader.py`
Парсер для кастомного формата YAML.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `validate(source)` | `str \| Path` | `bool` | Проверяет наличие steps, request, method |
| `parse(source)` | `str \| Path` | `TestModel` | Парсит YAML в TestModel |
**Внутренние методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `_parse_steps(steps)` | `list[dict]` | `list[StepModel]` | Парсит шаги |
| `_parse_request(request)` | `dict` | `RequestModel` | Парсит запрос |
| `_parse_extract(extract)` | `list[dict]` | `list[ExtractModel]` | Парсит извлечение |
| `_parse_assert(asserts)` | `list[dict]` | `list[AssertModel]` | Парсит проверки |
**Формат YAML:**
```yaml
name: "Test Name"
base_url: http://localhost:8080
variables:
email: test@example.com
steps:
- name: "Login"
request:
method: POST
url: /api/login
headers:
Content-Type: application/json
body:
email: "{{email}}"
extract:
- name: token
json_path: "$.token"
assert:
- type: status
value: 200
```
**Когда использовать:** Для собственных тест-спецификаций проекта.
---
### PostmanReader
**Файл:** `yamlreaders/postman_reader.py`
Парсер для Postman Collection v2/v2.1.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `validate(source)` | `str \| Path` | `bool` | Проверяет наличие info и item |
| `parse(source)` | `str \| Path` | `TestModel` | Парсит Postman Collection в TestModel |
**Внутренние методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `_extract_variables(data)` | `dict` | `dict[str, str]` | Извлекает переменные |
| `_extract_base_url(data)` | `dict` | `str` | Ищет переменную base_url |
| `_extract_auth(data)` | `dict` | `AuthModel \| None` | Парсит аутентификацию |
| `_parse_items(items)` | `list[dict]` | `list[StepModel]` | Рекурсивно парсит items |
| `_parse_item(item)` | `dict` | `StepModel \| None` | Парсит один request |
| `_parse_request(request)` | `dict` | `RequestModel` | Парсит HTTP запрос |
| `_parse_events(events)` | `list[dict]` | `list[ExtractModel]` | Парсит test scripts |
| `_parse_test_script(line)` | `str` | `list[ExtractModel] \| None` | Извлекает pm.environment.set() |
| `_convert_pm_to_json_path(pm_expr)` | `str` | `str` | Конвертирует pm表达式 в JSON-путь |
**Формат YAML:**
```yaml
info:
name: "Collection Name"
variable:
- key: base_url
value: http://localhost:8080
item:
- name: "Login"
request:
method: POST
url:
raw: "{{base_url}}/api/login"
path:
- api
- login
header:
- key: Content-Type
value: application/json
body:
mode: raw
raw: '{"email": "{{email}}"}'
event:
- listen: test
script:
exec:
- "pm.environment.set('token', pm.response.json().token);"
```
**Когда использовать:** Для импорта коллекций из Postman.
---
### OpenAPIReader
**Файл:** `yamlreaders/openapi_reader.py`
Парсер для OpenAPI 3.0/3.1 спецификаций.
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `validate(source)` | `str \| Path` | `bool` | Проверяет наличие openapi и paths |
| `parse(source)` | `str \| Path` | `TestModel` | Парсит OpenAPI в TestModel |
**Внутренние методы:**
| Метод | Вход | Возврат | Описание |
|-------|------|---------|----------|
| `_extract_base_url(data)` | `dict` | `str` | Берёт URL из servers |
| `_extract_auth(data)` | `dict` | `AuthModel \| None` | Парсит securitySchemes |
| `_parse_paths(paths)` | `dict` | `list[StepModel]` | Конвертирует paths в шаги |
| `_parse_operation(path, method, operation)` | `str, str, dict` | `StepModel` | Парсит один operation |
| `_build_request(path, method, operation)` | `str, str, dict` | `RequestModel` | Создаёт RequestModel |
| `_schema_to_example(schema)` | `dict` | `dict` | Создаёт example из schema |
| `_generate_extracts(operation)` | `dict` | `list[ExtractModel]` | Генерирует extraction |
| `_generate_asserts(operation)` | `dict` | `list[AssertModel]` | Генерирует asserts |
**Формат YAML:**
```yaml
openapi: "3.0.0"
info:
title: "API Name"
version: "1.0.0"
servers:
- url: http://localhost:8080
paths:
/api/login:
post:
operationId: "loginUser"
requestBody:
content:
application/json:
schema:
type: object
properties:
email:
type: string
responses:
"200":
description: "Success"
content:
application/json:
schema:
type: object
properties:
token:
type: string
```
**Когда использовать:** Для импорта API из OpenAPI спецификаций.
---
### get_reader
**Файл:** `yamlreaders/__init__.py`
Функция для автоопределения формата и получения appropriate reader.
| Параметр | Тип | Описание |
|----------|-----|----------|
| `source` | `str` | Путь к YAML файлу |
**Возврат:** `BaseReader` (YamlReader, PostmanReader или OpenAPIReader)
**Исключения:**
- `FileNotFoundError` — файл не найден
**Логика определения:**
| Признак | Формат | Reader |
|---------|--------|--------|
| `openapi:` в содержимом | OpenAPI | OpenAPIReader |
| `info` и `item` в YAML | Postman | PostmanReader |
| Иначе | Кастомный YAML | YamlReader |
**Когда использовать:** Когда нужно автоматически определить формат файла.
**Пример:**
```python
from yamlreaders import get_reader
reader = get_reader("tests/api.yaml")
model = reader.parse("tests/api.yaml")
```
---
## Примеры использования
### Базовый пример
```python
from models import TestModel, StepModel, RequestModel, ExtractModel, AssertModel
from models import Context, TestRunner
# Создаём модель теста
model = TestModel(
name="Тест логина",
base_url="http://localhost:8080",
variables={"email": "test@x.com", "password": "123456"},
steps=[
StepModel(
name="Логин",
request=RequestModel(
method="POST",
path="/api/login",
body={"email": "{{email}}", "password": "{{password}}"}
),
extract=[
ExtractModel(name="token", json_path="$.token")
],
assert_=[
AssertModel(type="status", value=200)
]
)
]
)
# Запускаем
context = Context(model)
runner = TestRunner(context)
result = runner.run()
# Результат
print(f"Тест: {result.passed}")
```
### Парсинг из YAML
```python
from yamlreaders import get_reader
from models import Context, TestRunner
# Автоопределение формата
reader = get_reader("tests/api.yaml")
model = reader.parse("tests/api.yaml")
# Запуск
context = Context(model)
runner = TestRunner(context)
result = runner.run()
print(result.passed)
```
### Парсинг из Postman
```python
from yamlreaders import PostmanReader
from models import Context, TestRunner
reader = PostmanReader()
model = reader.parse("exports/postman_collection.yaml")
context = Context(model)
result = TestRunner(context).run()
```
### Парсинг из OpenAPI
```python
from yamlreaders import OpenAPIReader
from models import Context, TestRunner
reader = OpenAPIReader()
model = reader.parse("docs/openapi.yaml")
context = Context(model)
result = TestRunner(context).run()
```
### Использование переменных
```python
model = TestModel(
variables={"host": "localhost"},
steps=[
StepModel(
name="Запрос",
request=RequestModel(
method="GET",
path="http://{{host}}:8080/api/users"
)
)
]
)
context = Context(model)
context.resolve("{{host}}") # "localhost"
```
### Извлечение данных
```python
from models import Extractor, Response, ExtractModel
context = Context(model)
extractor = Extractor(context)
response = Response(
status=200,
body={"user": {"id": 123, "name": "Test"}},
headers={}
)
extractor.extract([
ExtractModel(name="user_id", json_path="$.user.id")
], response)
print(context.extracted["user_id"]) # 123
```
### Проверка ответов
```python
from models import Validator, Response, AssertModel
validator = Validator()
response = Response(status=200, body={}, headers={})
# Проверка статуса
asserts = [AssertModel(type="status", value=200)]
print(validator.validate(asserts, response)) # True
```