← назад к разделу

Понедельник, в чате команды: «Выложили сборку на тестовый стенд, посмотрите». В сборке одна новая функция — оплата бонусами — и три починенных бага. До релиза два дня.

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

каждая сборка идёт через три прогона подряд сборка 214: дымовой не прошёл — дальше не идём ✗✗ не грузится каталог сборка 215: новое работает, сломалось соседнее✓ ✓ ✗✗ сломался поиск сборка 216: все трое зелёные — можно выпускать✓ ✓ ✓ ✓сборка уходит к пользователям дымовой продукт живой? новая функция делает что нужно? регресс старое не сломали? релиз назад в разработку каждый прогон отвечает на свой вопрос и останавливает путь, если ответ «нет»

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

Функциональное тестирование: делает ли то, что нужно

В задаче одна строка: «покупатель может списать бонусами до 30 % суммы заказа», и кажется, что проверка тоже одна. Но строка рассыпается на десяток вопросов: сколько продукт предложит списать при заказе на 1000 рублей, если на счету 500, а если 200; что будет ровно на 30 % и что — на копейку больше; считаются бонусы от исходной суммы или от уменьшенной промокодом.

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

Позитивные и негативные проверки

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

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

Нефункциональное: работает, но пользоваться невозможно

Бонусы списываются правильно. Только корзина после нажатия думает восемь секунд, на телефоне кнопка «Списать» уезжает за край экрана, а чужой бонусный счёт виден, если поменять в адресе одну цифру. Формально функция работает — пользоваться этим нельзя.

Нефункциональное тестирование отвечает не «делает ли», а «насколько хорошо»: скорость под наплывом покупателей, удобство, безопасность, работа в разных браузерах и на телефонах, устойчивость к сбоям — что будет, если интернет пропадёт между списанием бонусов и подтверждением оплаты. Отдельным прогоном ручной тестировщик занимается этим редко: держит углы в голове, пока идёт по функциональным проверкам, и заводит находку, когда что-то бросается в глаза (нефункциональные виды, кроссбраузерное тестирование).

Дымовой набор: стоит ли вообще начинать

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

Это дымовой набор (smoke) — название от незнакомого прибора в розетке: пошёл дым, до тонкой настройки дело не дойдёт. Он отвечает на один вопрос, имеет ли смысл начинать подробную проверку, и потому идёт широко и мелко: по одной короткой проверке на опорную функцию, только по счастливому пути, 10-15 минут на всё. Сборки приезжают по несколько раз в день, и часовой прогон перестанут запускать.

Не прошёл — сборку возвращают: пока каталог не открывается, остальные результаты ничего не значат. Главная грабля — разрастание: после каждого громкого бага кто-нибудь добавляет проверку в набор, через год он идёт час и его начинают пропускать. Лечится правилом «одна опорная функция — одна проверка», остальное переезжает в регресс.

Санитарная проверка: узкий заход после маленькой правки

Вечер перед релизом, прилетает правка в одну строчку: поправили текст ошибки при нехватке бонусов. Весь регресс — полдня, которых нет; не проверять — страшно. Тогда делают санитарную проверку (sanity): не весь продукт по верхам, как в дымовом наборе, а одну область целиком — списание бонусов во всех вариантах, которые правка могла задеть.

Разница по двум осям: дымовой набор — широко и мелко, по всей сборке, после каждой установки; санитарная проверка — узко и глубоко, по одному изменённому участку. Слова употребляют вольно, и «прогони санити» часто означает «быстро глянь, не развалилось ли»: спорить о терминах бесполезно, полезно переспросить, что прогнать и за какое время.

Повторная проверка бага: починили или сказали «починили»

Баг переехал в статус «исправлено» — это значит лишь то, что разработчик считает, что починил. Убедиться должен кто-то другой: это повторная проверка (re-test), в ней три шага.

Убедиться, что правка в этой сборке. Баг чинят в одной сборке, а вы открываете стенд со вчерашней: «не починили!» — самая частая ложная тревога новичка. Номер сборки обычно виден в интерфейсе.

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

Проверить вокруг — тот же сценарий на соседних данных: другая сумма, другой пользователь, отмена вместо подтверждения. Чинят часто описанный случай, а не причину, и соседний остаётся сломанным.

Не воспроизводится по шагам, а поведение странное — не закрывайте баг с пометкой «не воспроизводится», верните с описанием того, что видите сейчас (жизненный цикл бага).

Регресс: ломается то, чего никто не трогал

Добавили списание бонусов — перестали приходить письма о заказе: расчёт итоговой суммы трогали ради бонусов, а пользуются им и чек, и письмо, и возврат средств. Части продукта связаны сильнее, чем видно снаружи, поэтому у разработчика спрашивают не «что ты сделал», а «что это могло задеть».

Такой прогон называют регрессионным, в разговоре — регрессом: не сломалось ли из-за изменений то, что работало. Его путают с повторной проверкой, хотя вопросы разные — «этот баг починили?» и «не появилось ли новых из-за починки?»; делают их в один заход, поэтому второй и забывают.

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

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

Наборы под релиз: что гоняем и когда

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

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

Всё это — рабочий язык команды: «дымовой прошёл, иду по новой функции», «перепроверь баг на сборке 215», «нужен регресс по деньгам до пятницы» — и отвечать полагается так же, не «я всё посмотрел».

Коротко

  • Вид тестирования — не экран и не инструмент, а вопрос прогона: функциональное «делает ли обещанное», нефункциональное «насколько хорошо».
  • Большинство багов живёт в негативных проверках: счастливый путь уже прошёл разработчик.
  • Дымовой набор — широко и мелко, 10-15 минут на новую сборку; разросшийся до часа перестают запускать.
  • Санитарная проверка — узко и глубоко по одному изменённому месту; слово употребляют вольно, поэтому уточняйте объём.
  • Повторная проверка — те же шаги из отчёта на сборке с правкой плюс соседние данные; регресс отвечает на другой вопрос: не сломалось ли рядом.
  • Результат любого прогона привязан к номеру сборки: приехала новая — часть проверок устарела.

Что почитать дальше