docs: Added documentation for models and methods
This commit is contained in:
1 parent
c26c60f679
commit
2e7c69c5af
1 file changed
+730
@@ -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
|
||||||
|
```
|
||||||
Reference in new issue
Block a user