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

推荐订阅源

C
Cisco Blogs
Schneier on Security
Schneier on Security
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tenable Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threat Research - Cisco Blogs
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
NISL@THU
NISL@THU
L
Lohrmann on Cybersecurity
Scott Helme
Scott Helme
Webroot Blog
Webroot Blog
Project Zero
Project Zero
Google Online Security Blog
Google Online Security Blog
The Last Watchdog
The Last Watchdog
Spread Privacy
Spread Privacy
Hacker News: Ask HN
Hacker News: Ask HN
PCI Perspectives
PCI Perspectives
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
N
News | PayPal Newsroom
Help Net Security
Help Net Security
The Hacker News
The Hacker News
H
Heimdal Security Blog
O
OpenAI News
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
Cyberwarzone
Cyberwarzone
Simon Willison's Weblog
Simon Willison's Weblog
G
GRAHAM CLULEY
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Security Affairs
P
Proofpoint News Feed
S
Secure Thoughts
腾讯CDC
Google DeepMind News
Google DeepMind News
量子位
罗磊的独立博客

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

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Философия автотестов: управление, поддержка и флаки
Владимир Смирнов · 2026-05-08 · via Все публикации подряд на Хабре

Философия автотестов: управление, поддержка и флаки

Простой

7 мин

6.9K

Привет, меня зовут Смирнов Владимир, и я отвечаю за тестирование торгового бэкенда в EXANTE. Разработка кипит, регрессионные наборы автотестов растут - всё это сопровождается хаосом и различиями тестовых окружений, из-за чего неизбежно растёт и число нестабильных падений (ака флаки), за завесой которых могут теряться реальные проблемы. Как мы регулярно поддерживаем автотесты в приемлемом состоянии и стараемся не тратить на это слишком много времени? Об этом и поговорим.

Что происходит?

Как говорилось в предыдущей статье: написание как минимум одного автотеста на задачу является обязательной частью процесса тестирования у нас в EXANTE. Речь идёт о сервисных тестах: которые взаимодействуют с API конкретного микросервиса, существующего в живой среде со всеми её зависимостями. В текущей реальности одним тестом на фичу дело, конечно, не ограничивается: они пишутся пачками.

Рост количества автотестов сервисов одной из команд за год

Рост количества автотестов сервисов одной из команд за год

Но много не только тестов, но и тестовых джоб. У каждой команды несколько микросервисов, на каждый из которых существует джоба в CI/CD. Некоторые сервисы оказались жирноваты на функционал, но в ожидании распила, обзавелись огромным набором тестов. Мы уже выносим часть его в отдельные джобы - и некоторые из них прогоняются и напротив монолита, и напротив нового сервиса. Отдельные джобы тестируют особенности конфигурации сервиса на другом его инстансе. Есть функционал, который нельзя запускать в параллель - приходится выносить его в отдельную джобу и запускать отдельно от всех.

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

Причины падения могут быть любыми: как независящими от тестируемого сервиса, например особенности конфигурирования среды, которые мы не учли, или конфликты параллельно запускаемых тестов, так и вполне имеющими к нему отношение: гонка, зависимости от других сервисов и тому подобное. 

Закрывая глаза на отдельные падения, просто повторно запустив тесты или того хуже - навесив ретрай, мы рискуем обрести вроде бы хорошее покрытие, но с не очень понятным результатом. Можно ли доверять регрессу, в котором часть тестов нерегулярно падает по неизвестным нам причинам? 

Но самое опасное что, устав от малозначительных ошибок, мы рискуем пропустить действительно важные.

И что делать?

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

Гладко на бумаге

Окей, мы договорились с командой, выделили время в спринте, назначили дежурного, которого не грузим бизнес-задачами. Вот он открывает результаты ночных прогонов на окружении и начинает копать. Тут то и возникают минусы, которые заставляют скептически относиться к этому процессу: мы начинаем много времени тратить на дебаг и анализ падений, пытаясь раскопать их причины, и не успеваем чинить один, как на смену ему появляются новых два. Чиним 1 тест из 10, потратив на него неделю, и экстраполируем эту “эффективность” на оставшиеся поломки. Это сильно демотивирует. А пробегаясь по одним и тем же падениям каждое утро, мы замыливаем глаза. Как же выйти из этого порочного круга и чувствовать результат?

Концепция

Сделаем небольшое философское отступление. Для чего нам нужны автотесты? Очевидно, что первое, что приходит на ум: сэкономить наше время при проведении очередной проверки на регресс. Хорошо, переформулирую вопрос: какими они должны быть? Очевидно, что быстрыми и с широким покрытием, стремящимся к 100%. Окей, а что они должны делать? Очевидно, что должны проходить и всегда быть зелёными! 

Вот тут как раз скрыта сложность: такое отношение к тестам приводит не к их починке, а к маскировке других проблем. 

Тесты не нужны нам зелёными.

Сначала нужно осознать одну простую вещь (которая очевидна, но на практике почему-то не всем), перевернув понимание необходимости автотестов: они нужны нам не для того, чтобы проходить - они нужны нам для того, чтобы падать. Но! Падать так, чтобы вовремя и конкретно указывать на действительно важные проблемы.

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

Учитывая всё сказанное, мы изменили работу дежурного по поддержке автотестов и разбили её на несколько шагов

Шаг 1: Управляем Приоритетами

Ознакомившись с падениями, нужно выбрать тест для починки: нотификации о результатах прогонов уже сами подсказывают, за что взяться в первую очередь. 

В пайплайне тестовой джобы есть отдельные стадии: 

  • Стадия доступности сервиса (хэлсчеки, ведь нет смысла запускать тесты, если сервис не доступен), 

  • Стадия смоков (многие предустановки данных зависят от базовых API, так что имеет смысл самые используемые эндпойнты проверить отдельно, чтобы избежать каскадных падений) 

  • И, собственно, стадия регресса. 

Сообщение о падении на конкретной стадии сразу указывает на его критичность.

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

Известные нам флаки мы помечаем специальной маркой. Тест перезапускается только при совпадении ошибки, указанной в описании. В случае прохождения теста при повторном запуске - он отдельно упоминается в нотификации.

У нас также есть отдельный скрипт, который анализирует историю падений тестов и сообщает о повторяющихся изо дня в день. Он позволяет не пропустить что-то, что падает стабильно, но по какой-то причине было не замечено ранее.

Сообщение о результатах прогона автотестов

Сообщение о результатах прогона автотестов

Результат скрипта, отслеживающего повторяющиеся изо дня в день падения

Результат скрипта, отслеживающего повторяющиеся изо дня в день падения

Таким образом начало дежурства включает в себя: 

  1. Беглый анализ по приоритетам, разбиение на группы: критикал, быстрые решения, на исследование. 

  2. После чего происходит заведение багов, запросы командам (инфраструктуры, смежным), обсуждение на дейлике возникших вопросов.

  3. Расстановка марок с указанием заведённых задач: xfail, skipif, skip, rerun_for, которые автомёржятся без необходимости получения аппрува. Это позволяет команде не отвлекаться на эти падения в течение рабочего дня.  

Шаг 2: Быстрые Решения

Разобрались с тем, что выглядит критично, и понятно, куда уходят корни проблем. Что делать с оставшимися кейсами, причины падений которых покрыты туманом? Нет, не погружаться в их анализ - мы всё ещё стремимся экономить время. В дело вступает следующий алгоритм:

  1. А нужен ли тест? Действительно ли он проверяет что-то важное? Нет ли других (стабильных) тестов, которые упадут при проявлении такой же проблемы, которую покрывает данный тест? Может быть можно просто выключить его? Например, тест на сервис, который больше не разрабатывается.

  2. Хорошо, он нужен. А не слишком ли он сложен? Можно ли упростить его, максимально изолировав? Делать это легче, создавая новый тест, чем переписывая старый. Проверьте, действительно ли старый тест повторяет реальный путь системы? У нас были кейсы, когда промежуточный результат тест брал данные совсем не из того сервиса, из которого его получал сервис тестируемый - от этого всякие гонки и задержки, приводящие к непостоянным падениям.

    Как я писал выше: автотесты - не священная корова. Тот, кто написал его ранее, пусть даже вы - на тот момент могли ещё просто могли не уметь их писать или не обладали более широким пониманием системы.

  3. Не стоит сразу бросаться в дебри логов и эксперименты с воспроизведением падения. Сделайте ассёрты более информативными, добавьте логирование, специальные теги для отслеживания в логах, проверьте, покрыты ли все инструкции шагами (в случае наличия репортинга). После нескольких очередных падений это даст больше стартовой информации, чтобы приступить к действительно пристальному дебагу

  4. Кроме того падения анализируются специальным AI-ботом, который предлагает свои варианты решения на основе полученных данных из allure-репорта и анализа кода.

Шаг 3: Исследование и Сотрудничество

Ну вот наконец-то можно и приступить к старому-доброму дебагу-копанию. Но и здесь стоит применить подход, не позволяющий утонуть в потоке ускользающего времени. 

Алгоритм выглядит следующим образом:

  1. Анализ: выделяем пару часов на первичный анализ теста и сбор информации по возможным причинам падения;

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

  3. Проверка гипотез: экспериментируем, получаем новые вводные;

  4. Подведение итогов: снова созваниваемся, чтобы определиться, какое решение в итоге можно применить;

  5. Реализация: фиксируем решение. Оно может быть неокончательным, но приближает нас к более изолированному и стабильному состоянию..

С каждой итерацией вводной и проверенной информации становится больше, что позволяет совместно выработать максимально адекватное решение за минимальное время.

Удалять ли Старые Кейсы?

Тесты, которые были выключены, не теряются. Специальный скрипт собирает их, проверяет изменение статуса задач (линтер не позволяет проставлять марки без задачи) и сообщает, к каким из них нужно вернуться в случае изменения статуса на закрытый.

Напоминание о том, что нужно вернуться к тестам, задачи по которым уже выполнены

Напоминание о том, что нужно вернуться к тестам, задачи по которым уже выполнены

Что теперь делать с громоздкими тестами, которым написана более простая альтернатива? Которые написаны “неправильно”? Смело удалять. Или?..

Я снова переверну всё с ног на голову и выскажусь в их защиту. Если у вас есть время - не удаляйте их. 

Когда ваш регрессионный тест-сьют будет падать исключительно по делу, моментально давая вам обратную связь по ломающим нововведениям - займитесь отключёнными тестами. Они - источник странного и непредсказуемого поведения, которое позволяет узнать больше неочевидных деталей устройства тестируемой системы. 

Например, мы выяснили, что один из наших промежуточных сервисов, подгоняемый запросами клиента (теста), так спешил с изменением ещё не выставленной заявки, что ломал её саму. Создавая “правильные” тесты мы бы вряд ли задумались сэмулировать такую ситуацию, ведь ситуация выстреливала не всегда. Но благодаря небрежному тесту с элементом случайности мы обогатились ещё одним кейсом.

Резюме

Инструмент - не самоцель. Он служит конкретным задачам. Автотест - это инструмент. Его задача: быстро доставлять информацию о деградации функционала тестируемого сервиса. Для поддержания его в адекватном состоянии необходимо:

  1. Фильтровать и приоритезировать информацию о падениях: удалять из неё шум - это позволит снять когнитивную нагрузку с человека.

  2. Применять простые быстрые решения, улучшающие тесты итеративно.

  3. Ограничивать время на решение проблем. 

И, самое важное, делать это постоянно, не откладывая в бэклог. Это отдельный процесс, параллельный разработке функционала.

Применяя данный подход, мы ускорили “позеленение” тестов, а каждое новое падение для нас чаще сигнал о состоянии сервиса и окружения, чем загадка, тайна и Бермудский треугольник, поглощающий время сотрудников.