Тестирование с ИИ
Тестирование относится к областям, где ИИ одновременно сильно помогает и сильно обманывает. Помогает он потому, что тестовая работа объёмная и однотипная, а обманывает потому, что сгенерированный тест, который проходит, создаёт ощущение надёжности без её гарантии.
Вы отвечаете за то, чтобы рост объёма кода не превратился в рост дефектов. В этом блоке показано, где ИИ в тестировании экономит время и где он создаёт ложную уверенность.
Тестирование
Тестирование относится к областям, где ИИ одновременно сильно помогает и сильно обманывает. Помогает он потому, что тестовая работа объёмная и однотипная, а обманывает потому, что сгенерированный тест, который проходит, создаёт ощущение надёжности без её гарантии.
Базовое правило: ИИ генерирует тесты, а что именно проверять, задаёт человек. Рабочая последовательность выглядит так: человек (или ИИ по спецификации) формулирует, какие сценарии важны (основной путь, ошибки, граничные значения, безопасность), затем ИИ пишет тесты под эти сценарии. После этого человек убеждается, что тесты проверяют нужное: того, что они просто проходят, мало. Автоматика запускает их при каждом изменении.
Чего стоит избегать: просьбы «покрой этот модуль тестами» без указания сценариев. В ответ вы получите много тестов на очевидное и ни одного теста на то, что ломается на самом деле.
сценарии пишут тестировщики, синтетические данные согласуются с ИБ как замена копиям прода, регресс автоматизируется до пилота хотя бы на критичных путях.
отдельных тестировщиков часто нет, сценарии пишет сам разработчик – таблица из примера ниже помещается в описание задачи. Синтетические данные здесь не вопрос ИБ, а вопрос гигиены: копия прода на ноутбуке у стажёра – худшее, что может случиться с маленькой компанией после утечки.
Здесь ИИ особенно полезен: он генерирует реалистичные наборы данных, граничные случаи, невалидные значения и большие объёмы для нагрузочных тестов. Раньше это была рутина, которую делали по остаточному принципу.
У этой работы есть 2 ограничения. Первое касается регулируемых компаний: тестовые данные не должны быть копией реальных клиентских данных, но ИИ как раз помогает создать синтетические наборы с нужными свойствами. Второе касается всех: модель может генерировать данные, которые выглядят реалистично, но нарушают неочевидные правила вашей предметной области (несуществующие коды, невозможные сочетания), поэтому правила предметной области надо задавать явно.
О модульных тестах сказано в блоке 07. Интеграционные и сквозные автотесты относятся к следующему уровню, где ИИ помогает с самой трудоёмкой частью: он пишет шаблонный код для подготовки окружения, вызова сервисов и разбора ответов. Он также хорошо чинит тесты, которые сломались из-за изменения интерфейса при прежней логике.
Ограничение здесь одно: модель не знает, какие сквозные сценарии критичны для бизнеса. Сценарии выбирают люди, которые знают продукт.
Регрессионное тестирование проверяет, что новое изменение не сломало старое. С ИИ объём изменений растёт (по данным Faros AI, пул-реквестов становится почти в 2 раза больше), поэтому растёт и потребность в регрессе. По моему опыту, если регресс ручной, он становится узким местом быстрее, чем ревью.
ИИ помогает по 2 направлениям. Он расширяет автоматизированный регресс (генерирует тесты под существующее поведение, которое раньше проверяли вручную) и помогает выбирать, что запускать: анализирует, какие тесты затрагивает изменение. Второе направление сокращает время прогона, но требует аккуратности: пропущенный тест обнаружится на проде.
Отдельно об измерении: если вы одновременно внедряете ИИ и автоматизируете регресс, эффект от 2 изменений смешается. О том, как их разделить, – в блоке 11.
Это новое направление, которое появилось вместе с разработкой от спецификации. Если спецификация служит источником истины, её можно проверять до того, как написан код: на полноту (все ли сценарии описаны), на противоречия, на соответствие бизнес-требованиям. ИИ делает это хорошо: вы даёте ему спецификацию и просите найти, что в ней пропущено и что противоречит одно другому.
Смысл для руководителя такой: по моему опыту, ошибка, найденная в спецификации, стоит в разы дешевле ошибки в коде и на порядок дешевле ошибки на проде. Если вы переходите на спецификации, их тестирование для вас обязательный шаг, считать его дополнительным нельзя.
ПримерЗадание на тесты, которое можно взять за основу
Разница между «покрой модуль тестами» и рабочим заданием видна на той же задаче о суточном лимите переводов из блока 06. Сценарии пишет тестировщик, код тестов пишет модель.
| Сценарий | Тип | Вход | Ожидаемый результат |
|---|---|---|---|
| 30 переводов за сутки | Основной путь | Счёт с базовым тарифом, 30 успешных переводов подряд | Все 30 проходят |
| 31-й перевод | Граничное значение | Тот же счёт, ещё один перевод | Отказ LIMIT_COUNT_EXCEEDED, событие в журнале антифрода |
| Отменённый перевод не считается | Основной путь | 30 успешных, один из них отменён, затем новый | Новый проходит |
| Сброс в полночь | Граничное значение | 30 переводов в 23:59 по Москве, ещё один в 00:01 | Проходит |
| Сброс не по UTC | Ошибка, которую легко закрепить | 30 переводов в 02:00 по Москве (23:00 UTC, всемирного координированного времени), ещё один в 03:30 (00:30 UTC) | Отказ: московские сутки не сменились |
| Тариф «Премиум» | Вариация | 100 переводов, затем 101-й | 100 проходят, 101-й отклоняется |
| 2 перевода одновременно на 29-м | Конкурентность | 2 запроса в одну миллисекунду при счётчике 29 | Проходит ровно один |
| Персональные данные в журнале | Безопасность | Отказ по лимиту | В событии нет фамилии, номера карты и суммы |
2 правила при таком задании. Первое: колонка «Ожидаемый результат» заполняется до запуска модели и берётся из спецификации, а не из кода, иначе тест закрепит текущее поведение, в том числе ошибочное. Второе: строка «Сброс не по UTC» добавлена намеренно: это типичная ошибка сгенерированного кода, и без явного сценария модель напишет тест, который её не ловит.
Что говорят коллеги
Даниил и Мария о том, с чего начинать в тестировании.
Синтетические тестовые данные я понесу в ИБ первыми. Кажется, это единственное в блоке, что ИБ встретит с радостью: копии клиентских данных на тестовых средах у нас давно больная тема. С регрессом у меня проблема серьёзнее: он во многом ручной, поэтому тестировщики просто встанут, если ИИ удвоит число изменений. Сначала я автоматизирую регресс и только потом пущу генерацию кода шире пилота.
Мы попали ровно в ту ловушку, что описана в блоке: попросили покрыть модуль тестами, получили сотни зелёных тестов и пропустили ошибку, которую эти тесты закрепили. Помогло то, что тестировщики стали писать сценарии, а модель стала писать код тестов. Ещё одно наблюдение: проверка спецификаций моделью оказалась самым дешёвым способом ловить ошибки. На втором году я бы начинала с неё и только потом бралась за автотесты.
Обсуждение:
Главное из блока: ИИ пишет тесты, но что проверять, решают люди, которые знают продукт, а тест, который проходит, ещё ничего не гарантирует. С ростом объёма изменений первым узким местом станет ручной регресс, а самые дешёвые ошибки ловятся в спецификации. Дальше, в блоке 09, речь пойдёт о конвейере CI/CD: только он масштабируется вместе с объёмом кода.
Дальше блок 09 «CI/CD»: CI/CD означает непрерывную интеграцию и непрерывную поставку (continuous integration, continuous delivery): это автоматический конвейер, который собирает код, проверяет его и доставляет на среды.