Процессы и инструменты тестирования
Один и тот же запрос к базе, один и тот же код. На тестовой базе в тысячу строк он выполняется за 0,074 миллисекунды, и никто ничего не замечает. На прод-объёме в миллион строк - за 75,9 миллисекунды, в тысячу раз медленнее. Тест зелёный, релиз выкатили, прод лёг. Разница была только в количестве данных.
Стержень: половина «багов» - это среда или данные, поэтому сначала локализуешь проблему до слоя, а уже потом пишешь репорт.
// Формулировки: «что смотришь первым при баге?», «что такое staging?», «зачем изолированные тестовые данные?».
Замер: почему на тестовой среде зелено
Продолжу тот замер, он показателен. Поиск строки по адресу почты без индекса: на тысяче строк 0,074 мс, на миллионе - 75,9 мс. С индексом: 0,004 мс и 0,008 мс соответственно. То есть на маленькой базе индекс ускоряет в 19 раз, но обе цифры настолько малы, что разницы не видно глазами. На большой - ускорение примерно в десять тысяч раз, и вот его уже видно как разницу между «мгновенно» и «страница висит».
Индекс - это отдельная структура, по которой база находит нужную строку сразу, вместо того чтобы просматривать всю таблицу подряд. Пока строк тысяча, перебор всей таблицы дёшев, поэтому забытый индекс на тестовой среде не проявляется вообще никак. Это главная причина, по которой предпрод-среду делают похожей на прод - боевую среду с живыми пользователями - и по версиям, и по объёму данных.
// Отсюда лестница сред: dev (где разработчики ломают всё подряд), test (стенд тестировщика), staging - предпрод, максимально похожий на боевую среду по конфигурации, данным и железу, - и прод. Staging «примерно как прод», но с другими настройками, выключенными интеграциями и тысячей строк вместо миллиона, даёт ровно ту ложную зелень, что в замере выше.
- индекс
- структура, по которой база находит строку без перебора всей таблицы
- staging
- предпрод-среда, повторяющая боевую по настройкам и объёму данных
Локализация до слоя
«Сломался фронт» - самый бесполезный репорт. Фронтом называют то, что работает в браузере у пользователя: страница, кнопки, скрипты. Бэкенд - сервер, который считает и хранит данные. Показываю, как отличить одно от другого. Нажимаю «оплатить», открываю в браузере панель разработчика, вкладку Network - там видны все запросы, которые страница отправила на сервер, с их ответами. Вижу: запрос на оформление вернул код 500 и тело с текстом ошибки сервера. Коды делятся просто: 4xx - клиент прислал что-то не то (400 - кривые данные, 401 и 403 - нет прав, 404 - адреса не существует), 5xx - сервер сломался сам. Значит, фронт ни при чём, это бэкенд.
Дальше по порядку. Вкладка Console показывает ошибки скриптов самой страницы: если запросы отработали нормально, а Console красная - вот теперь это фронт. В ответе сервера обычно есть заголовок с идентификатором запроса, в моём замере это был X-Request-Id со значением req-a1b2c3: по нему в логах сервиса находится ровно этот запрос, а не все подряд. Потом при необходимости - проверка состояния в базе запросом и повтор вызова мимо интерфейса через Postman или curl (инструменты, которые отправляют запросы к серверу напрямую, без страницы).
// И банальное, что проверяют в конце: та ли это среда, включён ли фиче-флаг - переключатель, которым функцию можно выключить без выкладки новой версии. Половина «багов» лечится словами «функция просто выключена на этом стенде».
- Network / Console
- вкладки панели разработчика: запросы к серверу / ошибки скриптов страницы
- фиче-флаг
- переключатель функции без выкладки новой версии
Данные, учёт и метрики процесса
Тестовые данные - такой же актив, как код. Три источника: сгенерированные, фикстуры (заранее подготовленный набор с известным состоянием, который заливается перед прогоном) и обезличенные слепки прода - последние удобнее всех и опаснее всех, потому что персональные данные надо вычистить до, а не после. Общая изменяемая база на всю команду даёт мигающие прогоны по определению: мой тест ждёт трёх заказов, а сосед в этот момент создал четвёртый.
Учёт держат два инструмента. TMS (test management system) - система, где живут кейсы, прогоны и их связь с требованиями и дефектами; результат прогона в ней и есть аргумент в решении о релизе. Баг-трекер ведёт дефект по стадиям: заведён, взят в работу, починен, проверен, закрыт. Дисциплина полей (среда, версия, компонент) превращает его в пригодную статистику, а без неё это свалка текстов.
// Метрики процесса собирают под решение, а не под красивую панель. Доля дефектов, дошедших до прода, растёт - значит, дырявый регресс, то есть перепроверка работавшего раньше, и надо смотреть, каких проверок не хватило. Время прохождения регресса растёт - скоро он перестанет помещаться в релизный цикл. Если по числу не принимается никакое решение, его не стоит и считать.
- фикстуры
- подготовленный набор данных с известным состоянием под прогон
- TMS
- test management system: хранилище кейсов, прогонов и их связей
Как отвечать: «Что первым делом смотришь, когда «сломался фронт»?»
Первым делом я не пишу репорт, а локализую проблему до слоя, потому что половина таких случаев - это бэкенд, данные или среда. Открываю панель разработчика, вкладку Network, и смотрю на запрос, который стоит за сломанной кнопкой. Если он вернул 500 - сломался сервер, и репорт пойдёт другой команде, с телом ответа. Если 400 или 403 - фронт отправил не то или не хватает прав. Если запрос вообще не ушёл или ушёл, но страница на ответ не среагировала, - смотрю Console: там видны ошибки скриптов самой страницы, и вот тогда это действительно фронт. Дальше беру идентификатор запроса из заголовка ответа и по нему нахожу в логах ровно этот вызов, а не все подряд. Если нужно - проверяю состояние в базе запросом и повторяю вызов мимо интерфейса, чтобы понять, воспроизводится ли он без страницы. И проверяю банальное: та ли среда, не выключен ли фиче-флаг. В итоге в репорте у меня не «сломался фронт», а «такой-то запрос вернул 500, вот тело ответа и идентификатор запроса» - и разбор занимает минуты вместо дней.
Почему это сильный ответ: показан порядок действий (Network, коды ответа, Console, идентификатор запроса, база, вызов мимо интерфейса, среда и флаги) и объяснено, что даёт точная локализация.
На чём валят
- −Тестовая база в тысячу строк против прода в миллион: тот же запрос ускоряется индексом в 10 000 раз, и без него релиз ложится.
- −Репортить «сломался фронт», не заглянув в Network, где лежит 500 от сервера.
- −Общая изменяемая база на всю команду - прогоны ломают состояние друг другу.
- −Staging с другими настройками и выключенными интеграциями - зелено на стенде, красно в проде.
- −Собирать метрики, по которым не принимается ни одно решение.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 14, остальные разбираются в тренажёре.
- Зачем нужны отдельные среды (DEV, STAGE, PROD), а не тестировать сразу на проде?A)Чтобы проверять изменения в изоляции, не задев реальных пользователей и их данныеB)Чтобы ускорить работу приложения за счёт распределения нагрузки между средамиC)Чтобы каждый разработчик имел личную копию базы реальных пользователейD)Чтобы хранить резервные копии продакшена на отдельных серверах
показать ответ и разбор
+A)Чтобы проверять изменения в изоляции, не задев реальных пользователей и их данные// разбор: Разделение сред изолирует риск: на DEV разработчики ломают и чинят, на STAGE (тест/препрод) тестируют в условиях, близких к проду, и только проверенное едет на PROD к реальным пользователям. Тест прямо на проде грозит порчей боевых данных, простоем и утечками. Тестировщику важно знать, на какой среде он работает и насколько она соответствует проду — расхождения конфигов и данных дают баги, которые потом «не повторяются».
- Для чего тестировщик использует трекер задач вроде Jira?A)Чтобы писать и запускать автотесты прямо внутри интерфейса самого трекераB)Чтобы замерять покрытие кода тестами отдельно по каждому модулю проектаC)Чтобы хранить исходный код проекта и все его версии в историиD)Чтобы заводить и вести баги и задачи: статус, исполнитель, приоритет, история
показать ответ и разбор
+D)Чтобы заводить и вести баги и задачи: статус, исполнитель, приоритет, история// разбор: Трекер (Jira, YouTrack и подобные) — единое место, где живут баги и задачи: у каждого статус (открыт, в работе, на проверке, закрыт), исполнитель, приоритет, связи, комментарии и история изменений. Тестировщик заводит баг-репорты, следит за их движением, связывает с требованиями и релизами. Это не система контроля версий (код — в Git), не раннер автотестов и не инструмент покрытия — это учёт и координация работы команды.
- В чём роль тестировщика на Scrum-церемониях (планирование, дейли, ретро)?A)Тестировщик на церемонии не ходит, он подключается лишь в самом конце спринтаB)Только молча слушать статус, никак не влияя на оценки и решения командыC)Участвовать: оценивать тестируемость и риски на планировании, поднимать блокеры на дейлиD)Проводить и вести все командные церемонии вместо Scrum-мастера
показать ответ и разбор
+C)Участвовать: оценивать тестируемость и риски на планировании, поднимать блокеры на дейли// разбор: Тестировщик — полноценный участник, а не наблюдатель. На планировании он оценивает тестируемость историй, задаёт вопросы к требованиям, закладывает время на тестирование, подсвечивает риски. На дейли синхронизирует статус и поднимает блокеры (жду сборку, среда лежит). На ретро предлагает улучшения процесса (много багов на приёмке — подключаться раньше). Раннее участие (shift-left) ловит проблемы до кода, а не после.
- Зачем нужна система управления тест-кейсами (TestRail/TMS), если баги уже ведутся в трекере?A)TMS полностью заменяет баг-трекер: баги удобнее вести именно в нейB)TMS хранит тест-кейсы и прогоны с результатами и покрытиемC)TMS сама автоматически генерирует готовые тест-кейсы прямо из кода приложенияD)TMS нужна исключительно для автотестов, ручные кейсы в ней не ведут
показать ответ и разбор
+B)TMS хранит тест-кейсы и прогоны с результатами и покрытием// разбор: Баг-трекер отвечает на вопрос «какие дефекты есть», а TMS — «что и как мы проверяли». В ней живут тест-кейсы и чек-листы, тест-раны (прогоны) с результатами pass/fail/blocked, привязка к требованиям и релизам, отчёты о покрытии. Это даёт историю: что тестировали в прошлом релизе, что упало, какие области не покрыты. Найденный при прогоне баг заводят в трекер и связывают с кейсом — инструменты дополняют друг друга, а не заменяют.
- Чем уровни логирования (DEBUG/INFO/WARN/ERROR) помогают при разборе дефекта?A)Позволяют отфильтровать шум и быстро найти, где и что пошло не такB)Определяют, кто именно из разработчиков виноват в возникшем багеC)Автоматически задают приоритет заведённого бага в трекереD)Показывают процент покрытия кода приложения автотестами
показать ответ и разбор
+A)Позволяют отфильтровать шум и быстро найти, где и что пошло не так// разбор: Уровни ранжируют сообщения по важности: DEBUG — подробности для отладки, INFO — штатные события, WARN — подозрительное, но не сбой, ERROR — собственно ошибки. При разборе бага фильтруют логи по уровню: сразу к ERROR/WARN вокруг времени сбоя, а DEBUG включают, когда нужны детали. Это отсекает шум и ускоряет локализацию. К баг-репорту прикладывают релевантный фрагмент лога с ошибкой и её контекстом — это заметно ускоряет фикс.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.