Як я за 3 тижні побудував AI-розширення для Azure DevOps як side project
Усім, привіт. Мене звати Ігор Кошелєв. Я Senior QA Automation Engineer/Lead. Щодня працюю з C# + Playwright + NUnit. У цій статті хочу розповісти, як я за 3 тижні — вечорами та вихідними — побудував і запустив на Azure DevOps Marketplace публічне розширення, яке генерує тест-кейси з User Stories за допомогою AI.
Не буду прикрашати: шлях включав баги в продакшені, security audit з 25 знайденими проблемами і момент, коли я зрозумів, що мій bundler не бандлить те, що треба. Але по порядку.
Чому взагалі side project
Є така рутина в житті QA-інженера, яка нікуди не дівається, незалежно від того, наскільки ти досвідчений. Ти відкриваєш User Story, читаєш description, acceptance criteria, дискусію в коментарях. Потім створюєш Test Case Work Item. Пишеш title. Пишеш preconditions. Пишеш steps — action, expected result, test data. Потім наступний test case. І наступний. І так,
Це нескладна робота. Це навіть не цікава робота. Але вона з’їдає
Уявіть собі шеф-кухаря, який 40% свого часу витрачає не на створення страв, а на нарізку цибулі. Так, цибуля важлива. Так, треба нарізати рівно. Але чи не краще мати для цього помічника, щоб зосередитися на тому, що дійсно потребує досвіду та творчості?
Я спробував кілька AI-інструментів для генерації тест-кейсів. ChatGPT з промптом — результат generic, не враховує контекст проєкту і щоразу треба копіювати User Story вручну, потім копіювати результат назад в ADO. Copilot в IDE — не інтегрований з Azure DevOps, і взагалі не знає що таке Test Case Work Item. Можна написати скрипт, але тоді ти підтримуєш ще один інструмент замість того, щоб робити свою основну роботу.
Може, є щось спеціалізоване, що живе прямо в Azure DevOps?
Дослідження ринку: що вже існує
На Marketplace я знайшов два основні інструменти.
BakeQA — 712 установок, мінімум $100/місяць, без free tier. Один прохід AI, результат — просто текст. Нормально для proof of concept, але не для щоденної роботи. І $100/місяць за single-pass генерацію — це як платити за таксі бізнес-класу, яке довозить тебе до сусіднього будинку.
Copilot4DevOps від Modern Requirements — серйозний enterprise-продукт, $30-50 за користувача, 13+ фіч, SOC 2 compliance. Але теж один прохід AI, і ціна розрахована на великі команди з бюджетом.
Що мене не влаштовувало в обох: жоден не читає коментарі до User Story. А саме там часто живуть найважливіші уточнення. Один прохід AI — генерація та оцінка якості одночасно. Це якби один і той самий чоловік писав код і робив code review свого ж коду. Немає безкоштовного входу.
Я подумав: а що, якщо зробити краще?
Архітектурне рішення: Worker + Judge
Замість одного AI-виклику, який намагається одночасно генерувати і контролювати якість, я розділив процес на двох «спеціалістів»:
User Story → Worker (LLM виклик 1) → Чорнові TC → Judge (LLM виклик 2) → Фінальні TC
Worker — це як QA-інженер рівня Middle, який добре знає проєкт і може написати тест-кейси. Він отримує повний контекст: title, description, acceptance criteria, коментарі до User Story, налаштування проєкту (tech stack, business rules), сторінки з Azure DevOps Wiki. І генерує першу версію тест-кейсів.
Worker справляється непогано. Але він все одно продукує «шум»: окремий тест «verify page loads», три окремі тести для валідації пароля замість одного параметризованого, нечіткі expected results типу «дані відображаються коректно».
Judge — це як QA Lead, який перевіряє тест-кейси перед тим, як вони потраплять в backlog. Він бачить і оригінальну User Story і те, що написав Worker. Його завдання: злити тести, що перетинаються, видалити непотрібні, заповнити прогалини в покритті, переписати нечіткі assertions, поставити оцінку якості від 1 до 10.
Реальний приклад: Worker генерує 11 тест-кейсів для форми реєстрації. Judge зливає три тести email-валідації в один параметризований, видаляє standalone-перевірку «чи відображається форма» і додає відсутній кейс — реєстрація з email, який вже існує. Результат: 7 тест-кейсів, quality score 9/10.
Коштує в два рази більше токенів? Так. Але різниця між «ось тобі 11 тестів, розбирайся сам» та «ось 7 automation-ready тестів, можеш одразу кодити» — це різниця між інструментом і іграшкою.

Tech stack: чому TypeScript а не C#
Це питання, яке мені точно задали б. Я C#-інженер. Щодня пишу на C#. Чому для side project вибрав TypeScript?
Перша: full-stack consistency. Azure DevOps Extension SDK — це React (JavaScript). Azure Functions підтримують Node.js як runtime. Фронтенд, бекенд і core-логіка — все на одній мові.
Друга: platform-agnostic core. Я з самого початку проєктував архітектуру так, щоб core-пакет був повністю незалежним від Azure DevOps. Завтра я зможу взяти цей самий core і обгорнути його адаптером для Jira.
Третя: швидкість ітерацій. TypeScript + esbuild + hot reload дають мені цикл «змінив код → побачив результат» за секунди.
3 тижні розробки: від Hello World до Marketplace
Тиждень 1: фундамент
Перший тиждень — dev environment на Mac, publisher account на Marketplace, Hello World кнопка на Work Item Form. На практиці — день розбирався з Azure DevOps Extension SDK документацією.
Потім вже читав Work Item fields і коментарі. Тут я зіткнувся з першим сюрпризом: коментарі до Work Item приходять з API разом із системними повідомленнями. Їх треба фільтрувати, залишаючи тільки людські.
Далі — повний pipeline Worker + Judge з OpenAI GPT-4o-mini, створення реальних Test Case Work Items в Azure DevOps з XML Steps, TestedBy-Forward links, правильними Area/Iteration Path.

Тиждень 2: UI, тести, advanced features
На другому тижні — React UI для preview, вибору тест-кейсів, налаштувань. Додав preview з можливістю обирати, які тест-кейси створювати.
Далі — Project Knowledge. Це та фіча, яка перетворює generic AI output на щось реально корисне. Коли AI знає, що ваш frontend — це React з Material UI, а API використовує cursor-based pagination, тест-кейси приходять з релевантними selectors і realistic test data замість абстрактного «enter valid data».

Потім додав non-overlapping regeneration — розширення бачить вже прилінковані Test Cases і генерує тільки нові, що не дублюють існуючі. Плюс CSV та JSON export.
Тиждень 3: billing, security, launch
Stripe integration — окрема пригода. Webhooks, які приходять раніше, ніж ти встигаєш зберегти subscription. Race conditions між прямими API-викликами і webhooks. Оптимістична конкурентність з etag для лічильників використання.
А потім — security audit. Я провів повний аудит і знайшов 25 проблем. Двадцять п’ять.
Серед критичних: privilege escalation через price map (клієнт міг надіслати довільний Stripe price ID), відсутність HMAC-верифікації для upgrade tokens, race conditions на usage counters. Серед менш критичних: rate limiting, CORS hardening, SSRF prevention, XSS через innerHTML. Усі 25 проблем були виправлені. Без винятків.
Фінальний рахунок на момент запуску: 377 тестів.
Claude Code як інструмент розробки: чесний огляд
Що працює добре: boilerplate generation, refactoring, пошук багів, коли знаєш, що щось не так, але не бачиш, де, написання тестів, коли вже є implementation.
Що працює посередньо: складна бізнес-логіка з багатьма edge cases (billing, usage tracking), інтеграція з погано задокументованими SDK.
Що не працює: архітектурні рішення. Claude Code може допомогти реалізувати рішення, але рішення про Worker + Judge, про platform-agnostic core — це все людські рішення. AI — це молоток. Дуже хороший молоток. Але тобі потрібен архітектор, який скаже, де і який цвях забивати.
Мій workflow: я приймаю архітектурне рішення, описую його в CLAUDE.md і потім Claude Code допомагає з реалізацією. Знайти проблему — людина. Виправити проблему — разом.
Монетизація side project: як я думав про pricing
Одне з найскладніших рішень — як брати гроші за те, що ти побудував вечорами. Три принципи, до яких я прийшов:
Перший: безкоштовний вхід без бар’єрів. QA-інженер, який хоче спробувати новий інструмент, не має бюджету і не хоче проходити procurement process. Якщо для «просто подивитися» потрібна кредитна картка або реєстрація — 90% людей закриють вкладку. Тому free tier працює автоматично, без реєстрації, на основі organization ID.
Другий: платити за результат, а не за місця. Конкуренти беруть per-user — $30-50 за кожного інженера. Це означає, що в команді з 5 QA тільки один отримає ліцензію, а решта буде просити «а згенеруй мені теж». Я вибрав per-test-case модель з unlimited users — вся команда працює, платить компанія за обсяг.
Третій: собівартість, яка дозволяє чекати. Azure Functions на Consumption plan, OpenAI API, Azure Table Storage — загальна собівартість інфраструктури менше $30/місяць навіть під навантаженням. Це свідомий вибір для side project: я хочу мати runway для ітерацій, а не гонитву за revenue з першого дня. Якщо продукт реально корисний — гроші прийдуть. Якщо ні — я не банкрот.
Lessons Learned
esbuild та Azure Functions — це мінне поле. @azure/functions повинен бути в бандлі (не external), бо при deploy через zip монорепо hoisting не кладе його в правильне місце. Цей баг коштував мені цілий вечір діагностики
ADO iframe — це клітка. window.location.href повертає CDN URL галереї, а не dev.azure.com. window.open() з async/await блокується popup blocker. localStorage не працює. React тільки 16.
Security audit — це не опція. 25 проблем. Якби я запустився без аудиту, privilege escalation через price map дозволив би будь-кому змінити свій plan на найдорожчий без оплати.
«Потім напишу тести» = «ніколи не напишу тести.» 377 тестів здаються overkill для side project. Але кожен з них існує, тому що без нього щось зламалося.
Stripe — це нескладно, але billing logic — це складно. Сам Stripe чудовий. Але логіка навколо нього — webhooks vs direct API calls, race conditions, optimistic concurrency — це місяць роботи.
AI не замінює думання, AI замінює друкування. Найкращий результат я отримував, коли чітко знав, що хочу побудувати, і використовував AI як швидкий спосіб це реалізувати.
Підсумок
3 тижні. Один розробник. 377 тестів. 25 security issues знайдено і виправлено. Продукт на Azure DevOps Marketplace.
Чи варто будувати side project як QA-інженер? Однозначно так. Не тому, що ти обов’язково побудуєш наступний unicorn. А тому що ти побачиш продукт з іншого боку — не як той, хто тестує, а як той, хто будує. І це змінює перспективу назавжди.
Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.
8 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів