# API Checker - Models ## Архитектура Данные flowing через систему: ``` YAML/OpenAPI/Postman → Parser → TestModel → Context → Runner → TestResult ``` ## Классы ### TestModel (models/itm.py) Основная структура теста. | Поле | Тип | Описание | |------|-----|----------| | name | str | Название теста | | base_url | str | Базовый URL | | variables | dict | Переменные | | steps | list[StepModel] | Шаги теста | ### StepModel (models/itm.py) Один шаг теста. | Поле | Тип | Описание | |------|-----|----------| | name | str | Название шага | | request | RequestModel | HTTP запрос | | extract | list[ExtractModel] | Извлечение данных | | assert_ | list[AssertModel] | Проверки | ### RequestModel (models/itm.py) HTTP запрос. | Поле | Тип | Описание | |------|-----|----------| | method | str | GET, POST, PUT... | | path | str | Путь URL | | headers | dict | Заголовки | | body | dict | Тело запроса | | timeout | int | Таймаут | ### ExtractModel (models/itm.py) Извлечение данных из ответа. | Поле | Тип | Описание | |------|-----|----------| | name | str | Имя переменной | | json_path | str | Путь к значению | | source | str | body/header/status | ### AssertModel (models/itm.py) Проверка ответа. | Поле | Тип | Описание | |------|-----|----------| | type | str | status/json/header | | path | str | Путь к полю | | operator | str | equals/exists/gt/lt | | value | Any | Ожидаемое значение | ### Context (models/context.py) Контекст выполнения. | Поле | Тип | Описание | |------|-----|----------| | config | TestModel | Конфигурация | | variables | dict | Статические переменные | | extracted | dict | Извлечённые данные | | Метод | Описание | |-------|----------| | resolve(template) | Заменяет {{var}} на значение | | set_extracted(name, value) | Сохраняет извлечённое | ### Executor (models/executor.py) Выполняет HTTP запросы. | Метод | Описание | |-------|----------| | execute(request) → Response | Выполняет запрос | ### Extractor (models/extractor.py) Извлекает данные из ответов. | Метод | Описание | |-------|----------| | extract(configs, response) | Извлекает данные в Context | ### Validator (models/validator.py) Проверяет ответы. | Метод | Описание | |-------|----------| | validate(asserts, response) → bool | Все ли проверки прошли | ### TestRunner (models/runner.py) Оркестратор. | Метод | Описание | |-------|----------| | run() → TestResult | Запускает тест | ## Пример использования ```python from models import TestModel, StepModel, RequestModel, ExtractModel, TestRunner, Context config = TestModel( base_url="http://localhost:8080", variables={"email": "test@x.com"}, steps=[ StepModel( name="Login", request=RequestModel(method="POST", path="/login"), extract=[ExtractModel(name="token", json_path="$.token")], ) ] ) context = Context(config) runner = TestRunner(context) result = runner.run() print(result.passed) # True/False ``` --- # YAML Readers (yamlreaders/) ## Обзор Модуль для парсинга тест-спецификаций из различных форматов и конвертации их во внутреннюю модель `TestModel`. Поддерживаемые форматы: - **Кастомный YAML** — собственный формат проекта - **Postman Collection v2.1** — экспорт из Postman - **OpenAPI 3.0/3.1** — спецификация API ## Архитектура ``` ┌─────────────────────────────────────────────────┐ │ YAML Readers │ │ ┌─────────────┐ ┌─────────────┐ ┌──────────┐│ │ │ YamlReader │ │ PostmanReader│ │OpenAPIReader│ │ └──────┬──────┘ └──────┬──────┘ └─────┬────┘│ │ └────────────────┼────────────────┘ │ │ ▼ │ │ TestModel (ITM) │ └─────────────────────────────────────────────────┘ ``` ## Классы ### BaseReader (yamlreaders/base.py) Абстрактный базовый класс для всех парсеров. | Метод | Возвращаемое значение | Описание | |-------|----------------------|----------| | validate(source) | bool | Проверяет валидность файла | | parse(source) | TestModel | Конвертирует файл в TestModel | | load_yaml(source) | dict | Загружает YAML файл | **Параметры:** - `source: str | Path` — путь к YAML файлу **Исключения:** - `FileNotFoundError` — файл не найден - `ParseError` — ошибка парсинга YAML --- ### YamlReader (yamlreaders/yaml_reader.py) Парсер для кастомного формата YAML проекта. **Формат входного файла:** ```yaml name: "Test Name" base_url: http://localhost:8080 variables: email: test@example.com password: Test123! steps: - name: "Step Name" request: method: POST url: /api/endpoint headers: Content-Type: application/json body: key: value timeout: 30 extract: - name: variable_name json_path: "$.field" source: body assert: - type: status value: 200 - type: json path: "$.id" operator: exists ``` **Методы:** | Метод | Возвращаемое значение | Описание | |-------|----------------------|----------| | validate(source) | bool | Проверяет наличие steps, request, method | | parse(source) | TestModel | Парсит YAML в TestModel | **Пример использования:** ```python from yamlreaders import YamlReader reader = YamlReader() # Проверка валидности if reader.validate("tests/api.yaml"): model = reader.parse("tests/api.yaml") print(model.name, len(model.steps)) ``` --- ### PostmanReader (yamlreaders/postman_reader.py) Парсер для Postman Collection v2/v2.1. **Формат входного файла (YAML):** ```yaml info: name: "Collection Name" schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" variable: - key: base_url value: http://localhost:8080 - key: email value: test@example.com item: - name: "Request Name" request: method: POST url: raw: "{{base_url}}/api/login" host: - "{{base_url}}" 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);" ``` **Методы:** | Метод | Возвращаемое значение | Описание | |-------|----------------------|----------| | validate(source) | bool | Проверяет наличие info и item | | parse(source) | TestModel | Парсит Postman Collection в TestModel | **Особенности парсинга:** | Функция | Описание | |---------|----------| | Extract variables | Извлекает переменные из `variable[]` | | Extract base_url | Ищет переменную `base_url` | | Parse nested items | Рекурсивно обходит вложенные папки | | Parse request body | Конвертирует `raw`, `urlencoded`, `formdata` | | Parse test scripts | Извлекает `pm.environment.set()` для extraction | **Пример использования:** ```python from yamlreaders import PostmanReader reader = PostmanReader() if reader.validate("exports/collection.yaml"): model = reader.parse("exports/collection.yaml") print(model.name, len(model.steps)) ``` --- ### OpenAPIReader (yamlreaders/openapi_reader.py) Парсер для OpenAPI 3.0/3.1 спецификаций. **Формат входного файла (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" summary: "Login user" requestBody: content: application/json: schema: type: object properties: email: type: string password: type: string responses: "200": description: "Success" content: application/json: schema: type: object properties: token: type: string ``` **Методы:** | Метод | Возвращаемое значение | Описание | |-------|----------------------|----------| | validate(source) | bool | Проверяет наличие openapi и paths | | parse(source) | TestModel | Парсит OpenAPI в TestModel | **Особенности парсинга:** | Функция | Описание | |---------|----------| | Extract base_url | Берёт URL из `servers[0]` | | Extract auth | Парсит `securitySchemes` (basic, bearer, apiKey, oauth2) | | Parse paths | Конвертирует все methods (GET, POST, PUT...) в шаги | | Generate request body | Создаёт example body из `schema` | | Generate asserts | Автоматически добавляет проверку status code | | Generate extracts | Извлекает поля из response schema | **Пример использования:** ```python from yamlreaders import OpenAPIReader reader = OpenAPIReader() if reader.validate("docs/openapi.yaml"): model = reader.parse("docs/openapi.yaml") print(model.name, len(model.steps)) ``` --- ## Автоопределение формата Функция `get_reader()` автоматически определяет формат файла и возвращаетappropriate reader. ```python from yamlreaders import get_reader reader = get_reader("tests/api.yaml") model = reader.parse("tests/api.yaml") ``` **Логика определения:** | Признак | Формат | Reader | |---------|--------|--------| | `openapi:` в первой строке | OpenAPI | OpenAPIReader | | `"info"` и `"item"` в JSON | Postman | PostmanReader | | Иначе | Кастомный YAML | YamlReader | --- ## Исключения ### ParseError Выбрасывается при ошибке парсинга YAML. ```python from yamlreaders.base import ParseError try: model = reader.parse("invalid.yaml") except ParseError as e: print(f"Error at line {e.line}: {e}") ``` --- ## Полный пример ```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() # Выводим результат for step in result.steps: status = "✓" if step.passed else "✗" print(f"{status} {step.name}") print(f"\n{'PASSED' if result.passed else 'FAILED'}") ```