惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
爱范儿
爱范儿
量子位
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
博客园_首页
博客园 - 【当耐特】
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC

Все публикации подряд на Хабре

ИИ‑спасатель в кармане: как мы сделали агента для помощи при ЧС, который работает без интернета QNAME minimisation на практике: RFC 7816, реализация, грабли Агенты, роботы и мы: как ИИ перекраивает рынок труда в Европе От боли к npm install: TDLib для React-Native, или как я делал проект, а получилась библиотека Написание консольного симулятора баттл-арены на языке С++ с реализацией «умных» ботов Очень много букв… Или кейс по специфической настройке рабочего окружения Segmentation Fault: как оно устроено? Python в enterprise: момент, когда пора открыть Java не только ради собеседований MonoGame — игровой движок для тех, кто любит изобретать велосипеды Спасти рядового Буридана Рефакторинг выпадающих списков: от enum к конфигу-константе Free Porn Storage: передаём мемы в TLS-трафике, не привлекая внимания санитаров Мониторинг цен на Авито: MikroTik RouterOS Script Венесуэльская нефть после января 2026 Разговоры с ИИ Хотел упростить мониторинг проектов и в отпуск — пришлось обучать свой LLM. Часть 4. Тестирование Как вытащить ИТ из кризиса перегрузки, если найм запрещён Как мы подключили LLM к поддержке, а получили идеального лжеца Zero — новый agent-first язык программирования от Vercel, который изменит все (нет) Запускаем рекламу в дачной нише: какие креативы и форматы работают, на что смотреть в аналитике Паттерны организационного дизайна: практическое руководство Почему алгоритмы сливают твой депозит? 3 причины, о которых молчат «успешные» бэктесты Как «спят» вкладки в браузере Приоритет задач определяется не только ощущением срочности [Перевод] Махинации с прибылью Anthropic Project Loom: Virtual Threads, Scoped Values и preview #7 Structured Concurrency Мнения математиков о том, как ИИ опроверг гипотезу Эрдёша Слабоумие и отвага: как я за выходные сделала прототип ИИ-помощника для UX-дизайнера ИИ учит нас писать лучше. Или хуже? Как проектировать ИИ-инструменты, которые делают пользователей лучше «Раньше хотел каждый, сейчас и бесплатно не надо»: гаджеты, про которые мы все забыли ИИ-агенты в бизнесе: почему 80% компаний увольняют людей, но не получают ROI Как я строил ИИ-стартап, или Новые архитектурные риски 2026 4 интересных парадокса, рождающих жаркие дискуссии Рабочее место не-вайбкодера: настраиваем harness Когнитивный инжиниринг Feature Based Clean Architecture. Часть 1: Эволюция NestJS-приложения в неподдерживаемое состояние Как мы перестали бояться «пустых охватов» и сделали инфлюенс-маркетинг управляемым каналом роста Подключили B2B email-платформу к голосовым ассистентам через MCP. Архитектура, код, где ломается [Перевод] Почему AI-агенты ломаются на длинных задачах — и как обвязка помогает им дописывать приложения Облачно, возможны нейросети: кризис датасетов и ахиллесова пята систем машинного зрения — DIY-чтение на выходные Спустя 5 лет и $5 миллионов: почему создание нового языка для веб-разработки оказалось ошибкой Безопасная песочница Облачная LLM на 16 ГБ VRAM — часть 2: LangGraph Server, LangSmith и SDK Современный SSH-клиент для MS-DOS Как продвигать агентство недвижимости: от вывески до прямых эфиров MCP для GitHub + GitLab: инженерный гайд 2026 Вы платите OpenAI $20 в месяц, а он зарабатывает на вас ещё $100 млн за полтора месяца. И это только начало ИИ забирает работу «белых воротничков»: чему учить детей, чтобы выжить в будущем Практический ИИ-агент Python: LangGraph + Qdrant Как я делал ping и traceroute на iOS без entitlements — и почему это оказалось проще, чем UMP-консент для AdMob 4 MVP за 4 месяца, 30 холодных DM, 1 регистрация: building in public по-русски VPS-бастион: доступ к домашнему серверу без белого IP Kampus AI — нейросеть для генерации учебных работ для студентов и школьников Игры, помогающие продавать — примеры интересных рекламных акций с видеоиграми €500 в Telegram Ads принесли сделку на 350 000 ₽. Разбор B2B-кампании Чтение на выходные: «Разработка игр и теория развлечений» Рафа Костера Личный архив: сбор, бэкап, таймлайн фотографий INFOSTART TECH EVENT или INFOSTART A&PM EVENT — как понять, куда вам нужнее? Peer testing на основе Закона Линуса Релиз GitLab 19.0: ИИ-оркестрация, которая наконец-то догнала темп написания кода Как бизнесу оценить готовность к аттестации по новому Приказу ФСТЭК № 117 Технический гайд по сторис – часть 4: как мы добавили видео формат Представительство в арбитражном процессе: правовые различия между внешним защитником и инхаусом «Где новые фичи?» — Как AI-миграция легаси вернет IT-бюджет бизнесу Что нужно знать работнику про увольнение Новые требования Москвы к ЦИМ для АГР: готовый инструмент для проектировщиков в nanoCAD BIM Строительство WireGuard: простота и надёжность современного VPN-туннеля или секретное рукопожатие в тёмной комнате Выйдет ли GTA 6 в 2026 году, и чего ждать от игры Как меня назвали «невовлечённым», а я нашёл офшоры на Кипре Как LLM научила рекомендательную модель видеть больше, чем историю взаимодействий От хаоса к экосистеме: Модель зрелости комьюнити в бизнесе Свет, тьма, VEML7700 и Python Сказ о том, как мы процессы разработки в GRI меняли. Часть 2 Майский «В тренде VM»: громкие уязвимости в Linux, ActiveMQ, SharePoint и Acrobat Reader Статический анализ, заряженный ИИ: как LLM ищут уязвимости в коде и где их границы Блок “Процессы” и почему мы называем его нашим мини-n8n Как поменялся рынок интернет-рекламы: сравнение первых кварталов 2025 и 2026 годов: исследование click.ru Мониторинг Kerio Connect через Zabbix 7: разбор шаблона без агентов и regex по DAT 671 Allow в Claude Code за день: как родился сетап Spec-build 3 известные интересные задачи на логику Как айтишнику позаботиться о менталке и не перерабатывать OpenAI vs Anthropic: битва экс-коллег за корпоративного клиента и $1 трлн на IPO SEO для интернет-магазина в 2026: что поменялось и как с этим работать Сможете ли вы спроектировать Maven‑монорепозиторий для 5 микросервисов? 6 неудобных вопросов про американское произношение, которые айтишники боятся задать Неожиданная встреча: теория графов вновь помогла решить проблему в анализе Фурье Иллюзия трансформации: почему компании платят за спектакль вместо изменений AMD представила Ryzen 9 PRO 9965X3D и еще 5 процессоров, которые пойдут далеко не всем История IDE в Google Первые отзывы на новинки о System Design Влияние параметра planner_upper_limit_estimation на планы выполнения и профиль нагрузки PostgreSQL при использовании 1C Границы 100% разработки с агентами Быстрый OCR на основе Paddle Дооснащение любительской электровакуумной мастерской. Вакуумметр, течеискатель, полярископ Mythos: модель, о которой Anthropic не говорит. Реверс по жертвам — от 27-летней дыры в OpenBSD до побега из песочницы Как использовать Qwen3.7-Max и Grok Build 0.1 для ИИ-агентов в России Suricata IPS NFQueue with nDPI. Часть VI Важные изменения в защите информации в России: что нового? В чем секрет достоверного замедления биологического старения?
Как я сократил рутину QA до пары кликов: генератор API-тестов и тест-кейсов на LLM, которым хочу поделиться
ilya_akricki · 2026-05-23 · via Все публикации подряд на Хабре

Уровень сложностиПростой

Время на прочтение7 мин

Охват и читатели0

Кейс

Вступление

Привет, Хабр! Меня зовут Илья, я работаю Manual QA в команде, которая отвечает за качество продукта с большим количеством микросервисов, API и регулярными релизами. Если вы хоть раз писали тест-кейсы по тикету из Jira, потом руками собирали Postman-коллекцию по OpenAPI-спецификации, а после ревью документации обнаруживали, что половину сценариев забыли — эта статья для вас.

Я собрал инструмент, который автоматизирует три самых рутинных задачи QA-инженера: генерацию тест-кейсов, генерацию API-тестов и ревью документации. Всё это под одной крышей, с поддержкой любого OpenAI-совместимого LLM (включая локальные модели), с интеграциями в Jira, Confluence, TestRail, TestIT и Zephyr Scale.

Проект называется Test Generator Suite (TGS), и в этой статье я расскажу, какие проблемы он решает и как устроен внутри. Сразу оговорюсь: я не разработчик, я QA, и большую часть кода писал «как умею» — поэтому если в архитектурных решениях вам что-то покажется странным, я заранее согласен. Это инструмент для коллег по цеху, а не образец Python-инженерии.

Проблематика: почему я вообще за это взялся

QA-инженер в любой более-менее зрелой команде тратит огромное количество времени на повторяющиеся операции, которые с одной стороны требуют экспертизы, а с другой — большая их часть состоит из механического перекладывания информации из одной формы в другую.

Разберём типичный цикл моей работы над одной фичей. Аналитик пишет требования в Confluence, менеджер заводит задачу в Jira, разработчик прикладывает обновлённый OpenAPI-контракт. Я открываю эту задачу и начинаю делать примерно следующее: читаю описание, иду в Confluence по ссылке, смотрю спецификацию, формулирую у себя в голове сценарии, потом аккуратно раскладываю их по шаблону «название → предусловия → шаги → ожидаемый результат», заношу всё это в Zephyr Scale, после чего открываю Postman, дописываю к каждому эндпоинту проверки, тесты на негативные сценарии, валидацию схем ответа.

На крупной фиче этот процесс занимает день. И ведь это не творческая работа: 80% времени уходит на то, чтобы аккуратно зафиксировать то, что и так понятно из требований. Все решают эту проблему по разному: одни нанимают больше людей, другие выгорают, третьи ищут способы автоматизации. Я выбрал путь делегирования рутины LLM.

Параллельно с этим есть проблема качества входных данных. Если документация в задаче неполная или неоднозначная — тесты получатся такие же. Хороший тестировщик отлавливает это на этапе ревью документации, но это ещё один отдельный навык, который не у всех есть, и в любом случае это снова рутина: пройтись чек-листом по описанию и оценить, что забыли.

Из этих наблюдений и родилась идея TGS.

Что такое Test Generator Suite

Test Generator Suite — это веб-приложение на FastAPI, которое объединяет в себе три модуля, закрывающих основные сценарии моей работы.

Первый модуль — API-тесты. Я указываю Git-репозиторий с OpenAPI-спецификациями, выбираю нужные эндпоинты, и приложение клонирует репозиторий, разворачивает все внешние $ref-ссылки в единый документ, отправляет это в выбранную LLM-модель и возвращает готовую Postman-коллекцию v2.1 со всеми проверками: позитивные и негативные сценарии, валидация схем ответа, тесты на граничные значения. Коллекцию можно тут же отредактировать и запустить через встроенный Newman-runner, закоммитить обратно в репозиторий с коллекциями или скачать Postman коллекцию для глубокой доработки.

Второй модуль — Тест-кейсы. Я либо вписываю описание задачи руками, либо просто указываю номер Jira-тикета — приложение само подгружает описание из Jira и связанный контент из Confluence, отправляет это в LLM и возвращает структурированные тест-кейсы в едином формате. Их можно отредактировать прямо в UI и одной кнопкой залить в Zephyr Scale, TestRail или TestIT. Поддерживается работа с несколькими LLM одновременно — можно прогнать один и тот же ввод через GPT-4o и DeepSeek и сравнить результаты, есть feedback-петля: если в первой итерации что-то получилось не так, можно дать модели обратную связь и получить улучшенную версию.

Третий модуль — Doc Review. Это про качество входных данных. Модуль берёт описание задачи и прогоняет его через LLM с заточенным промптом, который оценивает полноту требований, тестируемость каждого пункта и потенциальные риски. На выходе — отчёт, который показывает, где в документации дыры, прежде чем по ней начнут писаться тесты. Это позволяет вернуть задачу аналитику до того, как я потрачу на неё несколько часов.

По части моделей TGS работает с любым OpenAI-совместимым эндпоинтом: можно использовать публичные API (OpenAI, DeepSeek, Anthropic через прокси), а можно поднять полностью локальную модель через vLLM или Ollama.

Как это работает изнутри

TGS — монолитное FastAPI-приложение со слоистой архитектурой. Я специально не пошёл в микросервисы: для инструмента, которым пользуется команда из 10-30 человек, это было бы избыточной сложностью, тем более для одного QA-разработчика без бэкенд-бэкграунда.

API-слой (tgs/api/) делает только три вещи: валидирует входные данные через Pydantic, вызывает функции из tgs/services/ и маппит исключения в HTTP-коды. Никакой бизнес-логики в роутерах нет

В сервисном слое лежит вся осмысленная работа. Например, openapi_bundler решает классическую проблему больших OpenAPI-проектов, где спецификация разбита на десятки файлов через $ref — модуль рекурсивно разворачивает внешние ссылки в один документ, оставляя внутренние ссылки (#/components/schemas/Foo) как есть, потому что их понимают и Postman, и Swagger-UI. Циклические ссылки я оставляю без инлайна — иначе ушёл бы в бесконечный цикл. Удалённые HTTP-ссылки игнорирую принципиально: загружать YAML с произвольных URL по запросу пользователя — это потенциальный SSRF.

postman_generator собирает payload для LLM из bundled OpenAPI, списка выбранных эндпоинтов и, опционально, существующей Postman-коллекции (чтобы модель сохранила стиль именования тестов и структуру переменных). Ответ модели парсится с учётом того, что LLM любят оборачивать JSON в markdown-блоки ```json ``` этот мусор аккуратно срезается, потом проверяется наличие обязательных полей info и item. Если LLM вернул что-то, что не похоже на коллекцию — кидаю понятную ошибку с первыми 500 символами ответа, чтобы можно было быстро понять, что пошло не так.

testcase_parser решает обратную задачу: LLM возвращает тест-кейсы в фиксированном Markdown-подобном формате, и парсер превращает этот текст в структуру, пригодную для UI и TMS. Я сделал его устойчивым к небольшим вариациям: модель может слегка нарушить регистр заголовков, перепутать число шагов с числом ожидаемых результатов — парсер это переживает без падения.

Слой tgs.llm — это OpenAI-совместимый клиент.
Добавление новой модели — это 6 строк в config.yaml:

models:
  gpt4:
    name: "GPT-4"                       # человекочитаемое имя в UI
    api_key: ""                         
    base_url: "https://api.openai.com/v1"
    model_name: "gpt-4o"
    temperature: 0.7
    enabled: true

Слой tgs.tms — это адаптеры test-management-систем. Базовый интерфейс TestManagementClient и три реализации: Zephyr Scale, TestRail, TestIT (интеграция с TestRail и TestIT не тестировалась). Выбор активной системы — одно поле test_management_system: "zephyr" в конфиге. Чтобы добавить новую, нужно реализовать интерфейс и зарегистрировать в tms.factory.

tgs.integrations — это интеграции с Atlassian: Jira для загрузки тикетов и Confluence для подгрузки связанной документации. Когда я вписываю в UI номер тикета, приложение идёт в Jira, забирает описание, потом проходит по ссылкам на Confluence-страницы и собирает их содержимое — на выходе получается единый текстовый блок, который и уходит в LLM. Это сильно лучше, чем копипастить описание задачи руками — а первые пару месяцев я копипастил.

Конфигурация и безопасность

Все настройки читаются в трёх местах с понятным приоритетом: переменные окружения, потом config.yaml в рабочей директории, потом config.example.yaml как fallback. Это позволяет держать в git конфиг с URL серверов, но без секретов, а секреты передавать через .env или secret-менеджер кластера. В контейнере можно вообще не монтировать конфиг — всё передать через ENV.

Конфигурация типизирована через pydantic-settings. У всех полей есть типы, валидация происходит на старте. Если в config.yaml опечатка — приложение не стартует и сразу говорит, какое поле невалидно. Никаких runtime-сюрпризов в стиле «ой, тут забыли поле, давайте упадём через час работы».

Все секреты (API-ключи, пароли, токены) обёрнуты в pydantic.SecretStr. Это гарантирует, что они не попадут в логи через repr()/str() и не утекут в JSON-ответы FastAPI

По умолчанию приложение слушает только 127.0.0.1. Если нужен внешний доступ — ставите перед ним reverse-proxy (nginx, Caddy, Traefik) с TLS и аутентификацией.

Деплой

Три сценария на выбор. Самый простой — docker compose up -d: репозиторий, копирование примеров конфига, заполнение, поднятие. Compose монтирует config.yaml, директории logs/, output/ и repos_cache/ из хоста, образ остаётся неизменным между запусками.

Второй вариант — локальный pip install -e .. Подходит для разработки и для одиночного использования: после установки появляется CLI-команда tgs serve, которая поднимает uvicorn.

Третий вариант — production-деплой в кластер. Тут уже на ваш вкус: можно собрать образ и катить его через свой реестр, можно сделать systemd-юнит с uvicorn, можно завернуть в Helm-чарт. Healthcheck /healthz, логи в stderr (плюс файловая ротация 10 MB × 5 файлов), стейтлесс — масштабируется горизонтально без оговорок.

Что получилось в итоге

Хочу быть честным: TGS — это не серебряная пуля и не замена тестировщика. Это инструмент, который убирает рутину и оставляет человеку то, что он делает хорошо: проверять, дорабатывать, искать неочевидные сценарии. Я как Manual QA в первую очередь делал его под себя — чтобы перестать тратить день на то, что не приносит ценности.

Сгенерированные LLM тест-кейсы всегда требуют ревью. Postman-коллекции — тем более, особенно для сложных API с нетривиальными сценариями. Качество результата сильно зависит от модели: на gpt-4o или claude-3.5-sonnet всё получается достойно, на локальных моделях результат будет плох и окна контекста скорее всего не хватит. Это нормально, и в документации я это прямо указываю.

Зато то, на что у меня раньше уходил рабочий день, теперь занимает 15-20 минут вместе с ревью. И главное — я трачу это время на проверку и доработку, а не на механическое перекладывание текста между системами.

Заключение

Главный урок, который я вынес из этого проекта: LLM в QA-инструментах хорошо работает не тогда, когда заменяет тестировщика, а когда снимает с него самую рутинную часть работы. Сгенерировать первую версию тест-кейсов по описанию задачи — это рутина, которую модель делает за 30 секунд. Доработать, поймать пограничные сценарии, прогнать тесты, найти баг — это всё остаётся за человеком.

И второй урок, уже личный: даже если ты не разработчик, а Manual QA, ничто не мешает собрать инструмент под свою боль. Современные LLM закрывают огромную часть рутины разработки — мне они сильно помогли с тем, что я бы сам писал годами. А итоговая ценность для команды получилась сильно больше, чем затраты времени.

Технологический стек, если коротко:

  • Backend: Python 3.10+, FastAPI, pydantic, pydantic-settings, httpx, GitPython, PyYAML.

  • Frontend: чистый HTML/JS без фреймворков. Это инструмент, а не SPA — реакта тут не нужно.

  • LLM: любой OpenAI-совместимый провайдер.

  • TMS: Zephyr Scale, TestRail, TestIT через REST API.

  • Atlassian: Jira, Confluence через REST API.

  • Test runner: Newman (опционально, для прогона сгенерированных коллекций).

  • Деплой: Docker, docker-compose, systemd-юнит, любой ASGI-runner.

  • Линт/типы/тесты: ruff, mypy, pytest.

Лицензия — MIT. Ссылка на репозиторий

Буду рад вопросам и обратной связи в комментариях или в Телеграмм @ilyaakrickij.