From 473f28fae19ba9eb64290c6f979df65931802fc7 Mon Sep 17 00:00:00 2001 From: Obrams Date: Sun, 21 Dec 2025 22:16:11 +0300 Subject: [PATCH 1/5] Enhance README with detailed design and architecture overview, including client implementations for REST, GraphQL, gRPC, and Kafka, along with testing strategies and stability improvements. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index a8580d7..8c6fefe 100644 --- a/README.md +++ b/README.md @@ -415,6 +415,36 @@ send_result, received = helper.send_and_receive("topic", {"data": "test"}) client.close() ``` +## Design/Architecture + +Проект демонстрирует не только умение писать тесты, но и способность строить общий инфраструктурный слой для разных типов интеграций. Каждый клиент решает специфичные задачи своей области и предоставляет единообразный интерфейс для тестов. + +### RestClient + +**Sync/Async поддержка:** Единый класс с lazy initialization для синхронного (`httpx.Client`) и асинхронного (`httpx.AsyncClient`) клиентов. Методы `get/post/put/delete` для sync, `aget/apost/aput/adelete` для async. Оба клиента создаются только при первом обращении через `@property`. + +**Retry механизм:** Все HTTP методы обёрнуты декоратором `@retry()` с экспоненциальной задержкой. Настраивается через `config.settings` (количество попыток, минимальная/максимальная задержка). Автоматически обрабатывает сетевые ошибки и временные сбои. + +**Хуки для логирования:** Структурированное логирование через `structlog` на уровне каждого запроса/ответа. Логируются endpoint, параметры, статус-коды. Поддержка Pydantic моделей через `_serialize()` — автоматическая конвертация в JSON. + +### GraphQLClient + +**Работа со схемами/queries:** Поддержка загрузки схемы через `fetch_schema_from_transport`. Выполнение запросов из файлов через `execute_from_file()` для переиспользования `.graphql` файлов. Методы `query()` и `mutate()` как семантические обёртки над `execute()`. Поддержка subscriptions через WebSocket транспорт. + +**Стратегия обработки ошибок:** GraphQL специфична — ошибки могут быть в `errors` массиве при HTTP 200. Клиент логирует предупреждения, но не бросает исключения (в отличие от HTTP ошибок). Метод `raw_request()` для тестирования негативных сценариев — возвращает `httpx.Response` для проверки статус-кодов и тела ответа. + +### GrpcClient + +**Единый helper вокруг stubs и методов:** Абстракция над низкоуровневыми gRPC stub'ами. Методы `unary_call()`, `server_streaming()`, `client_streaming()`, `bidirectional_streaming()` принимают `stub_class` и `method_name` как параметры — не нужно создавать stub'ы вручную. Lazy initialization канала через `@property channel` с поддержкой secure/insecure соединений. + +**Работа со streaming:** Все типы streaming (server, client, bidirectional) реализованы через генераторы. `server_streaming()` и `bidirectional_streaming()` возвращают `Iterator[Message]`, `client_streaming()` принимает `Iterator[Message]` как входной параметр. Единообразная обработка метаданных и таймаутов для всех типов вызовов. + +### KafkaClient + KafkaTestHelper + +**Решение проблемы «дождаться сообщения»:** Метод `consume_until()` с предикатом — получает сообщения до тех пор, пока условие не выполнится или не истечёт таймаут. `KafkaTestHelper.wait_for_message()` — высокоуровневая обёртка для ожидания сообщения по ключу или значению поля. Избегает проблем с порядком сообщений и race conditions. + +**Стабильность тестов:** Каждый consumer создаётся с уникальным `group_id` (через фикстуры с UUID) — изоляция тестов друг от друга. `consume_one()` и `consume_batch()` создают временные consumer'ы и закрывают их автоматически — нет утечек соединений. `send_and_receive()` в helper'е — атомарная операция отправки и получения для E2E тестов. Поддержка `auto_offset_reset="earliest"` для чтения всех сообщений в топике. + ## Примеры тестов ### REST тест From b4b5c9913fc56b7e3100ecf0f4581ac7d44ff5a0 Mon Sep 17 00:00:00 2001 From: Obrams Date: Sun, 21 Dec 2025 22:18:34 +0300 Subject: [PATCH 2/5] fix: add email-validator dependency for pydantic EmailStr --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 7ed94c6..188dd89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ # Валидация данных "pydantic>=2.5.0", "pydantic-settings>=2.1.0", + "email-validator>=2.0.0", # Генерация данных "faker>=22.0.0", From 4baacb76915f19d531f1542c04659debcc0515c5 Mon Sep 17 00:00:00 2001 From: Obrams Date: Sun, 21 Dec 2025 22:21:00 +0300 Subject: [PATCH 3/5] Add repository metadata: description and topics --- pyproject.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 188dd89..8007107 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,15 @@ license = {text = "MIT"} authors = [ {name = "API Tester", email = "tester@example.com"} ] +keywords = [ + "api-testing", + "pytest", + "grpc", + "kafka", + "graphql", + "sqlalchemy", + "allure", +] dependencies = [ # HTTP клиенты "httpx>=0.27.0", From b9168509ea5b8e6b3caf0dd37724e1909dfc8016 Mon Sep 17 00:00:00 2001 From: Obrams Date: Sun, 21 Dec 2025 22:21:26 +0300 Subject: [PATCH 4/5] Bump version to 0.1.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8007107..e0a00d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "api-test-python" -version = "1.0.0" +version = "0.1.0" description = "API testing framework in Python: REST, GraphQL, gRPC, Kafka, PostgreSQL, pytest, Allure" readme = "README.md" requires-python = ">=3.11" From 384c30332534f41fc4dc3095740441447e6de317 Mon Sep 17 00:00:00 2001 From: Obrams Date: Sun, 21 Dec 2025 22:22:05 +0300 Subject: [PATCH 5/5] Add Case study section to README --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 8c6fefe..d9a73a8 100644 --- a/README.md +++ b/README.md @@ -574,6 +574,16 @@ def test_pydantic_message(kafka_client, test_topic, user_event_message): - **allure** — отчётность - **structlog** — структурированное логирование +## Case study + +### Проблемы + +Какие типичные проблемы решает проект: разрозненные API‑тесты без единого клиента, отсутствие DB‑верификации, нет стабильного Kafka/gRPC тестирования, нет единого отчёта. + +### Решения + +Какие решения: единые клиенты для всех протоколов, Pydantic модели, SQLAlchemy + SQL assertions, Kafka helper, CI + Allure. + ## Лицензия MIT License