Playwright и TypeScript без знания TypeScript: инженер, слой ИИ и четыре контрольных звена.
Инженер по тестированию, имеющий опыт работы с Selenium и C#, создает фреймворк Playwright на TypeScript с помощью ИИ: структура, правила архитектуры, хуки и четыре этапа проверки задач.
Источники: I Built a Playwright Framework in TypeScript Without Knowing TypeScript — Using AI
Хранение данных, которое можно склонировать, содержащее информацию о навыках и правилах, а также Playwright, управляемый через MCP и способный самостоятельно пройти по всему приложению, легко обещать, но трудно реализовать. Такой проект уже существует в виде рабочего решения: достаточно его склонировать, выполнить одну команду, и тесты будут запущены на живом сайте. История его создания началась с устаревшего набора инструментов и вопроса о языках программирования.
Миграция, которая так и не была одобрена
Команда по тестированию в течение четырех лет пыталась развивать устаревший набор инструментов Selenium, а некоторые коллеги, которые позже перешли в отдел разработки, знали об этом ещё дольше. Основу этого набора составляли тысячи тестов интерфейса на языке C#, собранных на протяжении лет авторами, которые в основном уже покинули компанию. Переход на Playwright давно стоял в списке желаемого, ведь он быстрее, надежнее и удобнее в использовании, но переход так и не состоялся.
Причина была банальной. У никого не было ста свободных часов инженеров, которые можно было бы потратить на переписку кода, не приносящую никакой коммерческой пользы, а менеджер не может одобрить проект только на основании того, что «новый инструмент работает лучше». Технические аргументы всегда найдутся, однако чем больше пакет инструментов, тем дороже становится миграция, и тем меньше становятся очевидные преимущества. Переписку кода необходимо оплатить заранее и полностью. Ее эффективность никогда не отражается в цифрах отчета: она проявляется в меньшем количестве неудачных тестов и более быстром устранении ошибок в течение нескольких лет. Поэтому эта идея так и осталась нереализованной. Playwright и TypeScript постоянно появлялись в все большем количестве вакансий, а бездействие становилось все дороже как для проекта, так и для сотрудника.
Затем другая команда начала всё с нуля: без наследия, без множества тестов, которые обязательно должны работать, и без необходимости в миграции. Предложение разработать автоматизацию интерфейса и API привело к тому, что Playwright и TypeScript наконец стали использоваться в повседневной работе. Это также выявило один неприятный факт: Java и C# были знакомы, за ними стояло десять лет кода тестов, но речь шла о тестировании, а не о разработке, что требует совершенно другого уровня подготовки. JavaScript, TypeScript и сам Playwright были новыми инструментами. Возник вопрос, который два года назад звучал бы риторически: насколько незнание языка может сдерживать кого-либо в 2026 году, когда существует искусственный интеллект?
Откуда возник эксперимент
Ни один конкретный день не стал поводом для этого шага. Это развивалось постепенно, когда стало ясно, что простое тестирование и написание тестов ни к чему не приводят. QA обеспечивает свою работу не за счёт количества ошибок или количества строк кода, а путём совершенствования качества продукта с помощью процессов, документации, автоматизации и коммуникации, и со временем систематический подход оказался эффективнее индивидуальных усилий.
Два фактора способствовали этому в одном направлении.
Один из случаев возник из-за бота для торговли криптовалютами, написанного на Python с использованием Claude Code человеком, который не знал Python. Всё началось с восторга от первого успеха, но закончилось крахом, когда код стал слишком сложным для понимания, и никто не мог объяснить, почему проваливаются тесты и как их исправить. Урок заключался в разнице между написанием кода и созданием функционирующей системы: бот работал, но его невозможно было обслуживать. Не существовало никакой карты проекта, каждое исправление порождало новые проблемы, а токены исчезали в бесконечных описаниях симптомов вместо поиска причин.
Ещё одним стимулом стала повседневная работа, в ходе которой искусственный интеллект проникал в процессы контроля качества. Были проведены тесты, охватывающие весь цикл от задачи до завершённого теста, разработаны правила формулировок, согласно которым модель должна строго их соблюдать, а также обеспечена возможность повторения и контроля всего процесса. Коллеги использовали искусственный интеллект в качестве более умного поискового инструмента или «автомата по продаже кода». Почти никто не попытался оформить его в рамках системы, делающей его предсказуемым, что казалось расточительством возможностей, ведь именно систематизированная часть несёт настоящую ценность.
Эти два подхода привели к созданию проекта Playwright, сформулированного как гипотеза: насколько далеко может зайти инженер с прочными основами, если искусственный интеллект будет выполнять работу с текстом, и возможно ли создание полноценной рамки тестирования без написания ни одной строки на языке, которым инженер не может свободно владеть?
Почему TypeScript, а не C# или Java
Первая проверка была очевидной. Playwright также существует для C# и Java, поэтому, возможно, смена языка была ненужна. Оказалось, что разница не заключается в управлении браузером — эта часть одинакова везде: та же API, те же селекторы и те же браузеры. Разница кроется в том, как организованы и запускаются тесты.
В JavaScript и TypeScript Playwright поставляется с встроенным исполнителем тестов, обеспечивающим параллельную обработку, использование фикстур, генерацию отчетов и автоматический трейсинг. Для C# и Java такого инструмента нет. Команды используют то, что уже существует в их экосистеме — будь то xUnit, NUnit, JUnit или TestNG, — причем Playwright лишь предоставляет для них базовые классы, поэтому организация работы и параллелизм реализуются вручную. Именно это и является настоящим ограничением: не странная синтаксис или отсутствие метода, а необходимость заново создавать все элементы, включая параллелизм, изоляцию данных по потокам, систему управления и отчетность, хотя все эти проблемы уже решались ранее и их лучше избегать. Рядом с этим существовал вариант, уже полностью готовый к использованию, но на языке, которого никто не знал. Playwright развивался вместе с JavaScript, поэтому он является частью этой среды, а не посторонним инструментом.
Что на самом деле означает «создано без знаний»
Называть этот проект созданным без знаний — это не просто неточно, это прямая ложь. За этим стоит десятилетний опыт в области тестирования: разработка процессов с нуля и тестирование систем самых разных типов — от веб-приложений и API до мобильных приложений. Именно этот опыт помог избежать того, чтобы работа потонула в море сгенерированного кода. Синтаксис TypeScript и Playwright на протяжении всего времени оставался неожиданным фактором успеха.
Несколько курсов помогли. В ходе предыдущих экспериментов и при разработке этого проекта несколько курсов от Anthropic были посвящены проектированию агентов, объединению навыков и формулировке задач для ИИ. Они дополняли практический опыт, но не заменяли его. Важным был подход. Проект возник не из-за просьбы программиста о проведении тестов, а благодаря инженеру, который задал модели правила, архитектурные ограничения и то, что необходимо проверить, после чего позволил ей действовать в рамках этих ограничений, что превратило хаотичный процесс обмена информацией в упорядоченную работу.
Каркас с двумя оговорками
Прежде чем рассматривать структуру и её решения, необходимо упомянуть два момента.
Во-первых, данный проект представляет собой скелет, а не готовый продукт, который можно взять, адаптировать или изменить. Он предоставляется для демонстрации подхода, а не для демонстрации совершенства. Те, кто ищет готовый инструмент, будут разочарованы, тогда как те, кто ищет модель для создания системы на основе ИИ, смогут её найти. У команд есть свои ограничения, требования к безопасности и интеграции, и дизайн, подходящий для публичной демонстрации, может потребовать серьезной доработки в условиях корпоративных решений SSO, MFA, специальных правил для тестовых данных и системы управления тестами. Поэтому логика, лежащая в основе кода, является той частью, которая может быть перенесена в другие проекты.
Во-вторых, набор инструментов был минимальным. Он включал Claude Code с базовой ежемесячной подпиской стоимостью двадцать долларов, Visual Studio Code в качестве редактора, настроенный сервер MCP для Playwright, позволяющий модели самостоятельно исследовать приложение, и, вероятно, самое важное — свежий ум и немного свободного времени. Не требовались дорогие корпоративные решения, сложная инфраструктура или распределенные инструменты для тестирования. Всё работает на обычном ноутбуке, что также является частью смысла: для начала не нужно ничего сверхъестественного, лишь понимание того, что создается, и желание это сделать.
Что включает проект и как он организован
Целью является Toolshop — публичный демо-онлайн-магазин, созданный для практики автоматизации. Выбор имеет значение: это не замкнутая система и не бизнес-контекст, поэтому любой может скопировать репозиторий, установить зависимости одной командой и запустить тесты на живом сайте, без необходимости создавать учётные записи или изучать документацию.
В наборе тридцать семь тестов: тридцать четыре проходят, а три намеренно не проходят, чтобы в отчёте было видно, как выглядит сбой. Тесты API проверяют логику сервера, тесты интерфейса — пользовательский интерфейс, а гибридные тесты создают состояние через API, прежде чем проверить его в браузере. Этого достаточно, чтобы продемонстрировать архитектуру, но совершенно недостаточно, чтобы сказать что-либо о охвате продукта, который зависит от конкретного продукта и его бизнес-рисков, а не от количества тестов в демо-версии. Структура каталогов:
config/
env.ts // The only place where environment variables are read
timeouts.ts // Timeouts, also in one place
core/
run-user.ts // The user registered by this specific run
global-setup.ts // Register → UI login → data snapshot → download OpenAPI spec
global-teardown.ts // Cleanup after the run: remove favorites and the user
allure-labels.ts // Parses [Section / Subsection] from the test name into report structure
allure-categories.ts // Buckets for triaging failures in the report
api/
generated/schema.d.ts // Types generated from OpenAPI, never touched by hand
types.ts // Domain types derived from the schema
client.ts // openapi-fetch, paths and params checked by the compiler
contract.ts // Runtime validation of API responses against the schema
auth.api.ts // Typed clients on top of api/client.ts
pages/
base.page.ts // Base page class
components/ // Elements present on every page (site header)
auth/ // Page Objects for authorization pages
account/ // Account area: account, profile, favorites
shop/ // Catalog, product page, checkout
fixtures/
base.fixture.ts // All dependency injection, test/expect only imported from here
data/ // Strings and routes, so they don’t live inside tests
utils/ // Logger, reference data snapshot
tests/
auth/ // Everything auth-related in one folder
auth.api.spec.ts // API: login, token lifetime
registration.api.spec.ts
login.ui.spec.ts // UI: login form, errors, logout
catalog/
products.api.spec.ts
catalog.ui.spec.ts
cart/
cart.ui.spec.ts
favorites/
favorites.api.spec.ts
favorites.hybrid.spec.ts // Hybrid: state via API, verification via UI
profile/
profile.hybrid.spec.ts
contract/
contract.api.spec.ts // Matching live API responses against the spec
demo/ // Tests tagged @demo that fail on purpose
docs/ // Feature maps, checklists, test cases, plans
.claude/ // AI layer: rules, skills, agents, hooks```
Решения по структуре, масштабируемые с развитием проекта
- Сначала функции, затем уровни. Одно решение может показаться странным с первого взгляда, но оно определяет, насколько хорошо всё будет масштабироваться: тесты группируются по функциям, а уровень представляет собой суффикс имени файла, как в
login.ui.spec.ts,auth.api.spec.tsиcheckout.hybrid.spec.ts. Разработчик, изменяющий логику авторизации, находит все связанные тесты в папкеtests/auth/и не вынужден перебирать три отдельные папки. При тридцати тестах этого почти не замечают, а структура, основанная на уровнях, выглядит аккуратно. Однако при трехстах тестах папкаtests/ui/превращается в хаос из шестидесяти файлов, поскольку изменение любой функции влияет на все связанные с ней тесты, независимо от уровня. Разбросанные тесты превращают процесс анализа в поиск. - Когда даже папки с функциями становятся перегруженными. При наличии тысяч тестов папка с функцией может заполниться сотнями файлов. Следующим шагом является разделение на подпапки по подфункциям или сценариям, таким как
tests/auth/login/,tests/auth/registration/иtests/auth/password-reset/, что продолжает идею хранения контекста рядом с кодом. Также сотни тестов не должны находиться в одном файле, поскольку это приводит к появлению неразборчивого и непроверяемого «монстра». - Гибридный подход в качестве отправной точки. В демо-версии тесты разделены на тесты API, интерфейса и гибридные тесты, но реальный проект не обязан следовать этой структуре или создавать три слоя для каждой функции. Возможно, не существует отдельного API, достойного тестирования, или тесты интерфейса уже могут быть гибридными, при этом предусловия настраиваются через API или базу данных, а проверяется только та часть, которая связана с интерфейсом, в браузере. Это допустимо, поскольку разделение ради самого разделения является ошибкой. Написание гибридных тестов интерфейса с самого начала позволяет избежать чистых тестов интерфейса, которые передают состояние через браузер и тратят много времени. Структура — это средство, и каждая дополнительная абстракция увеличивает объем обслуживания.
Четыре решения, объясняющих остальное
В репозитории описаны четырнадцать архитектурных решений в файле .claude/rules/architecture.md; каждое из них отвечает на вопрос «почему именно так», а не «что это такое». Здесь пересказаны четыре из них, поскольку остальные лучше оставить в репозитории, чем перефразировать.
Каждая запускная процедура регистрирует своего собственного пользователя
Обычно используется один тестовый аккаунт, доступный для всех тестов. Это работает до тех пор, пока набор тестов не становится больше и они не выполняются параллельно. Тогда один тест очищает корзину как раз в тот момент, когда другой проверяет наличие товара в ней, что приводит к сбою, возникающему один раз из двадцати запусков и никогда не происходящему на самой машине отладчика.
Правило кажется простым: каждая задача имеет свою собственную среду изоляции. Это отличается от обещаний избегать общего использования данных или убирать следы после работы. Это означает, что физически нет никого, с кем можно было бы столкнуться. В публичной демонстрации эту роль выполняет новый пользователь, зарегистрированный в global-setup. В корпоративной среде это может быть заблокировано из-за ограничений на арендаторов, общих сущностей или уже существующих процедур воссоздания данных. Принцип остается прежним, а способ создания среды изоляции — это отдельный вопрос.
Тот же логик приводит к значению retries: 0. Повторная попытка служит лишь средством маскировки проблемы, а не гарантией её решения: она скрывает настоящую ситуацию с конкурентным доступом и откладывает последствия до момента, когда они станут наиболее серьезными. Тест, требующий повторной попытки, не является ненадежным, но указывает на сбой изоляции, и такой отчет заслуживает внимательного рассмотрения. Расходы здесь очевидны: в демо-версии регистрация пользователя требует одного запроса и всегда успешна, тогда как в других случаях механизм будет отличаться.
Типы определяются спецификацией, а тесты контракта проверяют эту спецификацию
Это два разных вида проверок, которые постоянно путают.
- Первая проверка происходит во время компиляции. У API есть документ OpenAPI, из которого генерируются типы; поэтому поле, упомянутое в коде, но отсутствующее в спецификации, мешает компиляции проекта. Этот процесс занимает две секунды и не требует запросов к серверу.
products/{productId}, тогда как в коде используется products/{id}. В другой раз они показали, что фильтр каталога вызывает функцию by_category_slug, параметр, который вообще отсутствует в спецификации. Сервер его принимает, и тесты проходят успешно, поэтому всё кажется «работающим». Однако параметр, не входящий в контракт, не может отклоняться от него — он может просто исчезнуть без следа.Следовательно, тест по контракту — это не проверка того, работает ли конкретный эндпоинт, а проверка того, является ли он тем эндпоинтом, на котором все договорились.
Токен, действительный триста секунд
В первоначальном дизайне токен сохранялся в файле после однократной авторизации перед запуском, чтобы все рабочие процессы могли к нему обратиться. Почти так и было сделано. Однако токен этого API действителен ровно триста секунд; это проверяется с помощью специального теста, сравнивающего два поля внутри токена, причем сам тест занимает больше времени. Самый медленный тест завершается с недействительным токеном, что приводит к ошибке 401, которая выглядит как проблема с правами, а не истечение срока действия, поэтому отладка начинается не с того места.
Поэтому в файле хранятся учетные данные, а не токены. Каждый рабочий процесс хранит свой собственный токен в памяти и обновляет его заранее. Из этого следует правило: всегда загружайте токен там, где он используется, и никогда не сохраняйте его в переменную в начале блока кода. Одна такая строка снова приводит к той самой проблеме, которую пытался устранить дизайн.
Данные снимка состояния загружаются один раз, а изменяемое состояние — никогда
Категории, бренды и страница продукта не меняются между запусками. Их можно загрузить один раз перед началом и передать тестам, так что тридцать тестов не будут запрашивать один и тот же список. Избранные элементы, корзина и профиль никогда не должны попадать в такой снимок, поскольку сами тесты их изменяют. Снимок изменяемого состояния не является способом оптимизации. Он создаёт данные с задержкой: тест считывает информацию, верной пять секунд назад, терпит неудачу, и кто-то пытается найти баг в приложении, в котором его нет.
Очистка также следует той же логике. Она выполняется по порядку: сначала сущности, затем их владельцы, и никогда не терпит неудачи; ограниченные права приводят лишь к предупреждению. Неудачная процедура разборки превращает один неудачный тест в неудачный запуск с неверным объяснением, что является худшим видом неудачи.
Слой ИИ
Подумайте о том, что происходит, когда Claude Code открывается в папке проекта и получает запрос «написать тесты для корзины». У модели есть только этот запрос. Она не знает, что общие учётные записи запрещены, что локаторы должны браться из проверенной карты, или что использование глобального счётчика в параллельном наборе тестов — это ловушка. Она делает предположения, причём довольно точные, поэтому код выглядит неплохо и, скорее всего, работает. Большинство людей останавливаются на этом этапе и считают, что это работа с ИИ.
Слой ИИ переформулирует задачу. Вопрос перестаёт касаться того, что предположит модель, и становится вопросом о том, что она должна знать и что она, возможно, никогда не сможет сделать. Он состоит из пяти компонентов, каждый из которых выполняет свою функцию.
- CLAUDE.md, загружается всегда. Файл, расположенный в корне проекта и загружаемый в начале каждой сессии. Он выполняет функцию вводного руководства для нового сотрудника, в данном случае модели, и представлен на двух экранах: что такое проект, где находятся элементы, пять самых важных моментов и что категорически запрещено. Слово «всегда» определяет лимит использования, поскольку каждый диалог оплачивает загрузку файла в контексте общения. В него включается только то, что необходимо каждый раз. Сорок стилистических правил помещаются в отдельный файл, на который делается ссылка.
.env не подлежат изменению. Команды git push --force, --no-verify и --amend автоматически отклоняются. Хук не пытается убедить и не объясняет ничего после этого. Действие не происходит, а в ответ указывается причина и соответствующий путь.Каждое понятие — в одной строке: CLAUDE.md — это материал для первого ознакомления новичка, правила — это стандарты команды, навыки — это руководства по процессам, агенты — это стажеры с ограниченным доступом, а хуки — это шлагбаум, который остается закрытым.
Тот же уровень для активных заявок
Абстракции имеют смысл лишь тогда, когда через них проходит реальная задача. Возьмём PROJ-431 — «оплата заказа картой». Обычная последовательность действий не связана с ИИ: кто-то тестирует функцию вручную, кто-то составляет чек-лист, кто-то преобразует его в тест-кейсы, кто-то автоматизирует этот процесс. Один человек может выполнять все четыре этапа, или их могут разделить между тремя людьми. Для конвейера не важно, кто что делает, и это и есть суть, поскольку конвейер просто добавляется к существующему процессу, а не заменяет его. Номер задачи служит своего рода нитью, проходящей через всё, и предпочтителен названиям функций или веток, поскольку он остаётся неизменным при смене названий и перераспределении задач.
Первый шаг: чек-лист
Инженер по контролю качества запускает соответствующую функцию и передает ей номер тикета. Поскольку MCP связан с Jira, функция сразу считывает содержимое тикета: описание, критерии принятия, а также, что часто бывает наиболее полезно, комментарии, в которых разработчик объяснял часть поведения функции, не обновляя при этом описание. Если MCP отсутствует или тикет пуст, инженер описывает функцию в промпте. Пайплайн нуждается в входных данных и не обращает внимания на их источник.
Затем начинается этап, для которого всё было создано. Система не формирует список проверок на основе текста заявки; она запускает агента для исследования, который заходит в приложение — локальную или тестовую среду, просматривает страницы функции, нажимает на элементы, читает актуальную структуру DOM, самостоятельно вызывает API и сравнивает полученные ответы с техническими требованиями. Только после этого составляется список проверок, основанный на том, что действительно существует, а не на том, что обещало описание задачи. Критерии приемки являются исходными данными, а не истиной, и половина несоответствий между ними и реальностью представляет собой первые баги задачи, обнаруживаемые ещё до написания кода.
В итоге получаются два файла, и самое важное здесь — правильно их разделить. Первый — это чек-лист: приоритизированные бизнес-сценарии в формате команды, а не проверки отдельных элементов. Красная рамка вокруг поля не является сценарием; зато блокировка пользователя с картой другого человека с указанием причины — является сценарием. Второй файл — это карта функций, содержащая проверенные локаторы, поля API, правила валидации и выявленные проблемы в процессе работы. Чек-лист представляет собой прямой результат выполнения задачи, а карта служит основой для последующих шагов. Инженер по тестированию читает чек-лист, отмечает ненужное, добавляет то, что известно только ему, и эта проверка служит контрольным пунктом: без одобрения ничего не может перейти дальше.
Второй шаг: тест-кейсы
Любой, кто выполнил первый шаг, может продолжить, или это может сделать другой человек, если ручные тесты и автоматизация выполняются отдельно. Второй специалист начинает с того же номера задачи и сам находит чек-лист и схему. Инженер решает, что нужно проверить — всё или только то, что было оговорено. Этот специалист преобразует эти пункты в тест-кейсы и для каждого кейса определяет один параметр: слой, к которому относится проверка.
- Правила, обеспечиваемые сервером, превращаются в тесты API.
- Элементы, видимые пользователем, становятся тестами интерфейса.
- Проверка, требующая пятнадцати кликов для настройки одного утверждения, превращается в гибридный тип теста, при котором состояние формируется через API, а проверяется только видимая часть.
Ошибки здесь стоят дороже, чем плохо написанные тест-кейсы, поскольку они приводят к медленному, дублирующемуся покрытию, которое позже никто не решается удалять. Этот инструмент также добавляет к каждому тест-кейсу раздел с информацией о сервисе: данные для использования, местоположения элементов, что должно быть уникальным, что подлежит очистке и под каким счетом. Для человека это выглядит как бумажная работа. Для следующего этапа это уже готовая спецификация. Инженер проверяет и утверждает её, что является вторым этапом контроля. Команды в Qase или TestRail могут здесь добавить инструмент, который загружает утвержденные тест-кейсы через API и позже отмечает их как автоматизированные.
Третий шаг: автоматизация
Этот инструмент автоматизации также берет номер задачи и загружает соответствующий чек-лист, примеры и саму карту. Его первое действие неожиданно: он проверяет, насколько актуальна карта. Каждый раздел имеет дату верификации, и всё, что старше месяца, перестаёт считаться фактом и превращается в утверждение. Инструмент ни отказывается, ни слепо доверяет этим данным. Он перемещает устаревшие элементы в раздел с рисками плана и передаёт решение человеку — либо провести повторную разведку, либо принять риск. Устаревший локатор всё равно будет отображаться, но лишь спустя три шага как сбой, причина которого остаётся неизвестной.
Далее идет план: какие файлы будут использоваться, какие данные потребуются для каждого теста, что создается перед его запуском и удаляется после него, какие страницы и методы клиента добавляются и какие вопросы остаются нерешенными. План является третьим и самым важным этапом, поскольку он определяет, можно ли безопасно запускать пакет тестов параллельно, а изменения в нем позже сопряжены с большими затратами.
После утверждения план передается агенту по написанию кода, характерной чертой которого является отсутствие способности к изобретению локаторов. Если в карте отсутствует необходимый локатор, он ни не предполагает его аналог, ни не скрывает этот недостаток, пропуская тест. Вместо этого он оставляет в коде примечание о том, что локатор не был проверен, и сообщает об этом. Тест все равно пишется и проваливается, что правильно, поскольку проблема остается видимой и не исчезает.
То, что раньше было отдельными командами, теперь входит в этот шаг: запуск, чтение ошибки, исправление. Каждому тесту предоставляются две попытки, после чего агент останавливается и признаёт поражение. Один последовательный запуск проверяет логику, а два параллельных — изоляцию. Дополнительных кнопок не требуется, поскольку ничто из этого не требует решения человека. Это процедура, закреплённая в правилах.
Здесь приведённые запреты являются особыми и не подлежат обсуждению:
- Не отключайте неудачный тест, чтобы сделать результат запуска «зелёным».
- Не увеличивайте количество попыток.
- Не скрыто ослабляйте проверки, чтобы они соответствовали наблюдаемому поведению.
Если приложение ведёт себя неправильно, правильным результатом будет красный тест.
Четвёртый шаг: проверка и сохранение
Проверка и сохранение изменений — это две отдельные навыка, а не один; такое намеренное разделение необходимо, поскольку шаг, начинающийся с намерения сохранить изменения, склонен находить причины для этого не делать. Проверка включает в себя знания, специфичные для проекта, которыми не обладает обычный рецензент: что здесь означает общая сущность, что ставит под угрозу токен в верхней части блока, почему использование глобального счётчика вводит в заблуждение. Каждая запись в списке связана с прошлым нарушением правил работы с этим набором инструментов. Чтобы предотвратить превращение этого разделения в формальность, при проверке оставляется «отпечаток» проанализированного различия, и сохранение изменений блокируется, если это различие с тех пор изменилось. Это не замок. Это вопрос с точным ответом: проверялся ли этот код или другой код? Разница между процессом и привычкой заключается именно в этом.
По окончании всей последовательности операций PROJ-431 содержит полную информацию: что исследовалось, что было выбрано для проверки, что обрабатывается автоматически, что остается в ручном режиме, что не будет автоматизировано и почему. Причина этого не в любви к документации. Через шесть месяцев во время анализа результатов кто-то обязательно задаст вопрос о том, почему тот или иной сценарий не был рассмотрен, и ответ на него должен уже существовать.
Что остаётся после завершения задачи
Основной риск при настройке не заключается в плохом сгенерированном коде. Проблема в том, что через шесть месяцев структура проекта превращается в беспорядочный набор файлов, и никто не знает, каким файлам можно доверять. Поэтому результаты работы имеют три отдельных срока жизни, и их смешивание запрещено.
- Правила действуют столько, сколько существует проект, и меняются только вместе с кодом.
- Карта функций существует в течение многих лет и принадлежит к функции, а не к конкретному заданию. Она пополняется разделами с датами, новыми страницами и новыми проблемами; она никогда не перестраивается заново для каждого задания.
- Чек-листы, случаи и планы относятся к одному заданию и становятся частью истории после его завершения.
Без такого разделения через год карта-локатор существует в десяти копиях, разбросанных по номерам задач; половина из них неверна, и невозможно определить, какая именно. Когда карта какого-либо элемента увеличивается в размерах, как это бывает с картами крупных элементов, решение похоже на решение проблемы с кодом: её необходимо разделить на части по естественным границам, таким как страница, подэлемент или сценарий, и вести краткий указатель того, что находится где. Действует также строгое правило ввода: в карту могут попадать только проверенные факты, то есть то, что агент действительно видел в рабочем приложении, с указанием даты. Догадки и пересказы информации из заявок туда не входят. Карта, принимающая их, является бесполезной в течение спринта, и позже невозможно отделить факты от догадок.
Нет никакого универсального рецепта. Четыре этапа обработки данных, пять компонентов слоя ИИ, ворота и сроки жизни артефактов — это лишь одно из возможных расположений элементов. Команды различаются по численности сотрудников, продукту и инструментам, поэтому половина деталей будет реализована по-разному. Некоторые решения сработают, некоторые потребуют корректировки, а некоторые не окажутся эффективными, и это вполне нормально.
Основная идея остается неизменной. Необходимо правильно построить слой ИИ, чтобы модель соблюдала правила команды в рамках её рабочих процедур, используя её артефакты, а рутинная работа оставалась за командой: просмотр заявок, написание похожих случаев, выбор слоев, поиск местоположений, повторная обработка и устранение сбоев, проверка на наличие тех же ошибок в сотый раз. Инженеры по тестированию не заменяются, а существующий процесс не отменяется. Время просто перестаёт тратиться на то, что можно передать другим.
Нужны ли всё ещё старшие специалисты?
Сейчас как никогда нужны старшие инженеры, выполняющие иные функции. Дэвид Хайнемейер Ханссон отмечал, что лучшее ускорение, достигнутое с помощью агентов, происходило благодаря самым опытным специалистам, способным оценить, подходит ли результат работы агента для использования.
Раньше инженеров ценили за написание кода, знание синтаксиса и быстрое выполнение задач, что имело смысл, когда основным продуктом был код. С появлением ИИ эта ценность изменилась в гораздо большей степени, чем на несколько процентов. Машина пишет код, а человек решает, что писать, зачем, в каких пределах и как проверить, что результат не является ложным.
Представьте двух специалистов. Первый открывает Claude Code и просит написать тест на вход. Тест пишется и проходит, и специалист чувствует себя продуктивным, что сегодня действительно так. Через месяц тест перестаёт работать, причина остаётся неизвестной, патчи вносятся случайным образом, токены тратятся, и в конце концов всё переписывается или тест удаляется и забывается.
Второй специалист сначала разрабатывает структуру: как изолировать тесты, какой шаблон будет соблюдаться клиентом API, как управлять токенами и что происходит с состоянием, меняющимся между тестами. Только после этого поступает задание модели: написать тест на вход согласно этим правилам.
В первом случае речь идет о тесте, который сейчас работает. Во втором — о системе, которая продолжает функционировать, поскольку она основана на архитектуре, а не на удаче. На небольшом количестве тестов разница незаметна: первый выполняет десять–пятнадцать тестов за десять минут, в то время как второй нуждается в двух часах или больше для выполнения базовых операций. Однако после сотни, двухсот или тысячи тестов и пятидесяти–ста запусков процессов разница становится очевидной.
Значит ли это, что необходимо изучать язык программирования?
Да, хотя и не для написания кода. Необходим язык, чтобы понимать, что сгенерировала ИИ, находить ошибки в сгенерированном коде, рассматривать запросы на внесение изменений и решать, что попадет в основную ветку. Синтаксис — это инструмент. Сложная структура, основанная на памяти, недоступна тестировщику в незнакомой области, но архитектура — это знакомая территория: как должна выглядеть система, как тесты остаются изолированными, как организованы пайплайны и что должно входить в хороший отчет. Именно эта основа сделала возможным проект Playwright.
Архитектура не возникает из простого запроса. ИИ может её предложить, иногда довольно хорошо, но архитектура — это выбор среди вариантов ответов, а не просто один из ответов. Модель предлагает пять вариантов, все из которых кажутся разумными. Однако тот вариант, который подойдёт за шесть месяцев при в десять раз большем количестве тестов и изменённых требованиях, не может быть автоматически сгенерирован. Он формируется на основе опыта, благодаря навыкам, приобретённым при устранении проблем с нестабильными тестами, пониманию причин, по которым тест проходит локально, но терпит неудачу в CI, а также выявлению скрытых связей между компонентами, способных привести к катастрофе.
Компаниям не нужны люди, которые лишь нажимают кнопки и пишут запросы в Claude Code или Cursor. Таких людей много, и их будет ещё больше; рынок переполнен разработчиками, которые считают, что нашли золото, но это чувство длится недолго. Нужны те, кто понимает, почему ИИ сделал что-то определённое, замечает его ошибки, формулирует задачи так, чтобы модель предоставляла рабочее решение, а не отшлифованную ошибку, и создаёт систему вместо того, чтобы постоянно вводить токены в бесконечные циклы «попробуйте снова, не так».
Опыт работы с процессами, автоматизацией и пайплайнами — это не просто архив данных. Это основа эффективной работы с искусственным интеллектом, которая отличает тех, кто создаёт хаос, от тех, кто создаёт системы. Раньше знания использовались для выполнения задач вручную. Теперь они служат для задания задач искусственному интеллекту и проверки результата. Роль изменилась, но ценность экспертизы осталась прежней. Это легче понять, ведь рядом с искусственным интеллектом сразу становится ясно, кто просто генерирует данные, а кто понимает, что было сгенерировано и почему.
Что показывает эксперимент
Фреймворк был создан на языке, которого его создатель не знает, и это не история о гениальности. Это история о том, чтобы не пытаться угадать, что сделает ИИ, а вместо этого уделять время объяснению правил игры: что допускается, что нет, и почему именно так, а не иначе. Это скучно, это не имеет ничего общего с атмосферой, и требуется время, прежде чем появится первый результат. Именно это и работает.
Репозиторий не доказывает, что инженеры устарели или что языки больше не имеют значения. Это живой пример того, как меняется роль инженера, когда ценность смещается от написания кода к формулировке задач, проектированию систем и проверке результатов. Ручное написание кода остается навыком. К нему добавился второй навык, который оказался не менее важным: понимание того, что было создано, почему и что будет дальше.
Искусственный интеллект не заменяет инженера. Он становится самым быстрым и послушным помощником, который только можно себе представить: неутомимым, не спорящим и всегда готовым к новой попытке. У него есть одна особенность: он с той же уверенностью предлагает как правильное решение, так и полную чушь, и только тот, кто разбирается в работе, может их отличить. Поэтому инженер должен оставаться за рулём как человек, знающий пункт назначения и дорогу, а не просто как тот, кто держит руль.
Связанные статьи
- MAF 1.0, LangGraph или CrewAI? Выбор фреймворка агента в 2026 году — Сравнение Microsoft Agent Framework 1.0, LangGraph и CrewAI по таким аспектам, как состояние, память, отладка, протоколы, пути в Azure и стоимость, с кратким алгоритмом принятия решения и схемой внедрения.