Exploratory Testing: три истории применения тест-дизайна

Меня зовут Алексей Чаплиц. Имея за плечами более 20 лет опыта вне IT-индустрии, я стал тестировщиком ПО три года тому назад. Больше о том, как и почему я стал Software Tester, можно узнать из моего интервью ведущим подкаста QAGuild .

Это статья — моя первая проба пера в сфере тестирования, в частности на тему Exploratory Testing. Моя главная мотивация — поделиться небольшим опытом и ноу-хау с теми, кому это может пригодиться.

Под термином Exploratory Testing я понимаю не столько «свободный» стиль ручного тестирования, сколько осмысленное и систематическое, хотя и творческое, исследование причинно-следственных связей. Цель такого тестирования — оптимизация работы тестировщика, а его итог — отсутствие дорогостоящего устранения багов на продакш-уровне и наличие качественного продукта.

В статье читатель найдет три истории. В каждой описаны по одному методу тест-дизайна, которые я, зная того или нет, применял. Их анализ сделан задним числом (постмортем). Больше об этих методах можно узнать в книге «Explore It!» Элизабет Хендриксон.

История первая: как C.R.U.D. помог мне проверить GUI

Пару лет назад я присоединился к небольшой, но распределенной команде разработки, которая состояла из пяти человек — Requirements Engineer/PO/UX Designer (в одном лице), двух разработчиков и двух заказчиков-инженеров из отдела R&D.

Я получил задачу тестирования ПО для работы с файлами XML-формата для управления программируемых станков для высокоточной лазерной резки металла.

Контекст тестирования

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

Использованная техника тест-дизайна

Книга «Explore It!» описывает простую, но эффективную пошаговую технику тест-дизайна — C.R.U.D. (Create, Read, Update, Delete). Обычно она применяется для проверки различных элементов в реляционных базах данных со структурой parent-child. Я применил этот подход для тестирования GUI вышеупомянутых станков, в которых использовались файлы с такой же структурой.

XML-файл с множеством параметров для управления станком

Шаг 1: Create (создание файлов)

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

Однако для создания негативных тестов я редактировал тестовый файл, заменяя параметры нужного типа на неприемлемые, например, int вместо double. Таким образом создавал «новые» файлы.

Диалог с сообщением об ошибке после введения параметра недопустимого типа

Шаг 2: Read (чтение файлов)

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

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

Диалог с сообщением об ошибке при открытии испорченного файла

Шаг 3: Update (обновление файлов)

Программа позволяла обновлять данные в файлах — как внутри программы, так и снаружи. При этом она должна была оповестить об изменениях в соответствующем диалоговом окне с возможностью сохранить их. Для проверки этого функционала я либо вносил изменения в параметры в UI или в текстовом редакторе в то время, как этот файл был открыт в программе, затем закрывал его.

Шаг 4: Delete (удаление файлов)

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

Тестовая сборка в TestRail для проверки функционала предупреждения об отсутствии запрошенных файлов

Результат анализа поведения тест-объекта

Программа работала большую часть тестов, как и ожидалось, под нормальной и стрессовой нагрузкой. И это благодаря тщательно проделанной работе Requirements Engineer’а и разработчиков каждый спринт.

Несколько тщательно выписанных пользовательских историй для стартовой страницы приложения

Что можно было изменить

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

Вывод

C.R.U.D. (Create, Read, Update, Delete) — простой и эффективный метод тест-дизайна. Я рекомендую его к применению по назначению, то есть в реляционных базах данных, или в аналогичных кейсах. Если вы знаете о противопоказаниях для использования метода, пишите в комментариях к статье.

История вторая: как я определял покрытие тестами больших рисков

На новом проекте (речь о нем пойдет подробнее в третьей истории), куда я пришел на замену выбывшего тестировщика, было три уровня тестирования, с тремя командами и тестовыми кампаниями. Я стал членом третьей команды, которая занималась регрессионным и smoke-тестированием еженедельных релизов и их хотфиксов.

Контекст тестирования

В проекте уже существовали тестовые кампании для наших целей. И хотя они покрывали основной функционал, из их содержания и описания нельзя было понять, покрывали ли они большие риски. Для того чтобы убедиться в этом, я применил технику тест-дизайна из книги «Explore It!».

Использованная техника тест-дизайна

Книга предлагает следующие три шага:

Этот подход имеет элементы классического управления рисками проекта и продукта, а его успех зависит от качественного анализа (см. первые три шага). Как оказалось, именно он стал моим главным фокусом.

Шаг 1: Составить список стейкхолдеров «в теме»

Вот как выглядел мой список:

Шаг 2: Узнать у стейкхолдеров о текущих жалобах и будущих страхах, связанных с продуктом

Вот такие вопросы я задал каждому из стейкхолдеров:

Пример анализа House of Quality

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

«Радар» рисков

Шаг 3: Проверить базу данных с описанием критических багов и их кластеров

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

Шаг 4: Протестировать с помощью известных техник с граничными переменными, вариациями данных, состояний и т. п.

Этот шаг я не применял (см. результат анализа ниже).

Результат анализа поведения тест-объекта

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

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

«Ты сделал двойную работу!» — скажет читатель. Согласен. Однако я смог убедиться в том, что большие риски были покрыты сборками. До этого момента, это было не очевидно на моем уровне тестирования.

Что можно было изменить

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

Применив подобный подход, можно было бы:

Вывод

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

История третья: как я «ловил» невоспроизводимый баг

Мое задание на этом проекте было непростым. Оно состояло в том, чтобы автоматизировать с помощью специального инструмента сценарии ручных тестов для Streaming Media Box (далее SMB). SMB — это приставка мультимедийных потоков, которую мой тогдашний работодатель — телекоммуникационная фирма — активно поставлял десяткам тысяч своих клиентов (см. фото).

Streaming Media Box (приставка мультимедийных потоков) с ПУ

Будучи новичком в автоматизации, я медленно, но уверенно двигался вперед к целям проекта, пока не уперся в невоспроизводимый баг, который блокировал принятие менеджером целой тестовой сборки. Что было делать?

Контекст тестирования

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

Скриншот экрана ТВ с пользовательскими профилями с разными именами

Создание профиля состояло из четырех этапов:

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

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

Пошаговое решение проблемы

Книга «Explore It!» предлагает «поймать» невоспроизводимый баг в четыре шага:

В своем анализе (уже задним числом) я использовал шаги 1, 2 и 4.

Шаг 1: Собрать доказательства, и на их основании найти закономерности появления бага

Шаг 2: Провести мозговой штурм факторов, которые окружают проблему

1. Что говорят другие тестировщики? Первая идея: таймауты (периоды ожидания) перед исполнением автокоманд в скриптах недостаточны. Однако они были вполне достаточны для ожидания ответа от бэкенда.

Вторая идея: скрипт автотеста исполняет команду «Нажать ОК» множество раз в то время, пока клиент регистрируется через SSO на главные сервер. Но, как показала проверка, многократное нажатие кнопки ОК не останавливало создание профиля с любым другим именем.

Третья идея: профиль с тем же именем уже существует на одном из нескольких SMB после первого удачного запуска тестовой сборки. Это уже было известно и подтверждало некую закономерность.

2. Что говорят инженеры, ответственные за бэкенд? Первая идея: аккаунт созданного профиля имеет скрытые детские профили, оставленные после ранних тестов, которые не отображаются в UI SMB. Проверка и удаление таких профилей в кабинете пользователя, однако, не решило проблемы.

Вторая идея: однажды созданный профиль никогда не удалялся с главного сервера. Проверка подтвердила этот факт и указала на ранее описанную закономерность.

Шаг 3: Использовать модель состояний (state models) для фиксации времени появления проблемы

Этот этап не применялся полноценно в анализе. Время появления бага было обнаружено на первом этапе анализа (см. п.1 выше).

Шаг 4: Провести предметное обсуждение проблемы с экспертами, которых затрагивает проблема

«Случайный» разговор с любознательным администратором бэкенда из Голландии, который прибыл на квартальное планирование в наш офис, помог мне посеять начальный интерес к теме. В результате завязалась длительная переписка в Slack-чате по этой проблеме с видео- и текстовыми логами. В свою очередь, это помогло мне поддерживать в нем интерес к ее решению.

После обсуждения с сисадмином из Голландии я поднял снова проблемный вопрос перед руководством. В итоге этот администратор снова открыл обсуждение вопроса в уже существующем тикете в Jira. В конце концов, он удалил у себя на сервере профиль с тем же именем, который был создан на другом SMB и — о, чудо! — проблема падающей сборки решилась сразу. Теперь им надо было работать над тем, чтобы этот профиль удалялся всегда.

Результат анализа поведения тест-объекта и взаимодействия участников

Что можно было изменить

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

Во-вторых, по возможности избегать создания сборок из взаимосвязанных тестов, которые имеют «встроенный» потенциал проблем.

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

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

Вывод

Индуктивный метод (от деталей — к закономерностям) анализа проблемы невоспроизводимого бага, предложенный в книге «Explore It!», помог, пусть и постмортем, проследить разрешение проблемы падающей тестовой связки. Его этапы могут служить схемой решения подобных проблем.


Буду рад узнать о вашем опыте в Exploratory Testing. Делитесь им в комментариях. Спасибо!

Опубліковано: 25/09/20 @ 10:00
Розділ web дизайн

Рекомендуємо:

5 советов начинающим программистам: как выбрать специализацию
DevOps’ный C++ и «кухонные войны», или Как я начал писать игры во время еды
5 книг, которые влияют на мировоззрение, от Senior Project Manager Тараса Федорука
Продвижение в топ 1 интернет-магазина в высококонкурентной нише — кондиционеры
«Мені здавалося, що IT — це про престиж, гроші та свободу». Розповідь фронтенд-розробниці, що пішла зі сфери