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

Эквивалентное разбиение (Equivalence Partitioning)

Описание метода: эквивалентное разбиение предполагает разделение множества входных данных на несколько классов или групп эквивалентности по определённому признакуtestengineer.ru. В пределах одного класса все значения считаются подобными и предполагается, что система обработает их одинаково. Вместо перебора всех возможных входных значений, достаточно выбрать по одному-несколько представительному значению из каждого класса и протестировать ихtestengineer.ru. Это резко сокращает число тестов, хотя не гарантирует отсутствия ошибок на невыбранных значениях внутри класса – мы лишь предполагаем, что протестировав типичных представителей класса, мы покрыли и остальныеtestengineer.ru.

Когда применять: метод эффективен, когда есть большой диапазон входных данных или множество однотипных значений. Разбиение на классы позволяет выбрать несколько примеров вместо тестирования каждого значенияtestengineer.ru. Например, при тестировании поля ввода, принимающего числа от 1 до 1000, логично разбить диапазон на категории (недопустимо меньше минимума, допустимый диапазон, недопустимо больше максимума) и взять по одному числу из каждой категории вместо проверки всех 1000 чисел. Если же входных данных немного или они не образуют естественных групп, то смысл эквивалентного разбиения уменьшается – в таких случаях можно напрямую протестировать все варианты или применить другие техникиtestengineer.ru.

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

Ограничения: главный компромисс – риск пропустить дефекты в значениях, которые не были выбраны из класса. Если внутри одного эквивалентного класса значение обрабатывается иначе (например, особый граничный случай, на который не обратили внимание), то тест, взявший другой представитель класса, этот дефект не обнаружит. Кроме того, техника приносит пользу в основном при действительно широком диапазоне данных; если набор входных значений небольшой, разбиение на классы может быть избыточным. В реальности эквивалентное разбиение часто комбинируется с анализом граничных значений для усиления покрытия.

Пример: предположим, интернет-магазин рассчитывает стоимость доставки заказа в зависимости от суммы покупки. Тарифы такие: доставка стоит $15 для заказов на сумму менее $100, $5 – для заказов более $100, и бесплатно – для заказов от $300 и вышеtestengineer.ru. Здесь можно выделить три класса эквивалентности по стоимости заказа: (1) менее $100, (2) от $100 до $299.99, (3) $300 и большеtestengineer.ru. Для тестирования достаточно взять по одному значению из каждого диапазона, например: $50 (класс 1), $150 (класс 2), $500 (класс 3). Ожидаемые результаты: для $50 доставка $15, для $150 – $5, для $500 – бесплатно. Мы предполагаем, что любой другой заказ из этих же диапазонов даст тот же результат, поэтому все промежуточные значения (скажем, $20 или $250) можно не проверять отдельно – это и экономит время.

Анализ граничных значений (Boundary Value Analysis)

Описание метода: анализ граничных значений является развитием эквивалентного разбиения. Здесь также выделяются эквивалентные группы (диапазоны) входных данных, но тестированию уделяются именно значения на границах этих диапазоновtestengineer.ru. Идея в том, что ошибки программы чаще всего проявляются на стыке смежных диапазонов (из-за неправильного включения/исключения границы, переполнения, смены логики и т.п.). Поэтому вместо произвольного представителя класса берутся непосредственно граничные значения каждого класса – как допустимые, так и выходящие за границу.

Когда применять: всегда, когда в требованиях есть числовые диапазоны, пределы допустимых значений или любые пороговые условия. Границы – наиболее рискованные точки, и их проверка обязательна. Анализ граничных значений особенно полезен для числовых полей, дат, размеров, количеств и прочих диапазонных параметров. Эту технику применяют сразу после эквивалентного разбиения: сначала определили классы, затем дополнительно протестировали границы между ними. Она важна как на уровне отдельных полей ввода, так и на интеграционном уровне – например, границы между модулями или компонентами системы (там тоже часто возникают дефекты на стыках логики).

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

Ограничения: в сравнении с эквивалентным разбиением, этот метод требует большего числа тестов, ведь каждой границе соответствуют как минимум два значения (на нижней и верхней стороне)habr.com. То есть если класс был один, EP мог бы протестировать его одним значением, а BVA – двумя (минимум и максимум). В итоге тестов больше, но взамен мы получаем уверенность в корректной обработке границhabr.com. Ограничением может быть ситуация, когда границ как таковых нет (например, множество дискретных допустимых значений без непрерывного диапазона) – тогда прямая выгода от этой техники отсутствует. Также, если в системе очень много параметров с границами, количество граничных тестов может расти значительно, и здесь уже нужно расставлять приоритеты.

Пример: возьмем предыдущий пример с тарифами доставки: границы диапазонов $99.99 ↔ $100.00 и $299.99 ↔ $300.00 – ключевые точки, где меняется правило расчета. Применяя анализ границ, протестируем значения вокруг этих порогов. Для границы $100: проверяем $99.99 (самое большое значение, когда еще должна взиматься $15) и $100.00 (минимальное значение, при котором доставка уже $5); также имеет смысл проверить значение сразу за границей – $100.01 (чтобы убедиться, что не наступает льготная доставка по ошибке)testengineer.ru. Аналогично для границы $300: $299.99 (максимум, когда доставка ещё $5) и $300.00 (минимум, когда доставка должна стать бесплатной)testengineer.ru. Кроме того, не лишним будет проверить недопустимые значения прямо за границами – например, $0.99 ниже нижнего предела (должно быть отклонено системой)testengineer.ru. Таким образом, мы покрываем все переломные точки: чуть ниже, ровно на границе и сразу выше – там, где чаще всего и скрываются дефекты внедрения граничных условий.

Таблицы принятия решений (Decision Table)

Описание метода: таблица принятия решений – это техника, позволяющая наглядно представить комбинации нескольких условий и соответствующие им действия (результаты)habr.com. В таблице по одной оси откладываются условия (факторы, влияющие на поведение системы), а по другой – правила или сочетания этих условий. На пересечении указывается ожидаемый результат или действие системы при данной комбинации условий. Каждая колонка (или строка, в зависимости от оформления) таблицы соответствует отдельному тестовому сценариюhabr.comhabr.com. Таким образом, заполнив таблицу всеми возможными значимыми комбинациями входных условий, мы фактически получаем полный набор тест-кейсов для данной логики.

Когда применять: эта методика незаменима, когда система имеет сложные правила с несколькими условиями, особенно если условия могут сочетаться произвольным образом. Например, бизнес-правило может зависеть сразу от трёх параметров – тогда вручную легко упустить какую-то комбинацию. Таблица решений гарантирует, что мы рассмотрим все возможные сочетания условий(или по крайней мере все значимые, если явно исключить заведомо невозможные случаи). Использовать decision table стоит при тестировании функционала, описанного большим числом логических операторов (if-else) или бизнес-правил, включающих несколько факторов одновременно. Также табличная форма удобна для коммуникации – её можно показать аналитикам или разработчикам, чтобы убедиться, что все случаи учтеныhabr.com.

Преимущества: главный плюс – наглядность и полнота охвата. Таблица гораздо понятнее длинного описания в тексте: сразу видно, какие комбинации проверяются, а какие – нетhabr.com. Ещё одно преимущество – каждое правило в таблице уже служит прототипом тест-кейса, то есть составив таблицу, мы фактически сгенерировали набор тестовhabr.com. Это экономит время при написании тестовой документации. Кроме того, построение таблицы помогает выявлять проблемы в самих требованиях. Визуализируя правила, тестировщик может заметить логические пробелы или противоречия: например, отсутствует реакция на какую-то комбинацию условий – значит, в требованиях пропущен сценарий (это сразу бросается в глаза в форме таблицы)habr.com. Таблица «освежает взгляд» на знакомое ТЗ, позволяя по-новому скомбинировать условия и обнаружить ранее неучтенные случаи.

Ограничения: у техники практически нет минусов в контексте ее применения, но есть ситуации, когда строить таблицу нецелесообразноhabr.com. Во-первых, если логика очень простая (1–2 условия или очевидные зависимости), таблица лишь добавит лишнюю работу – там и так всё ясно из описания. Во-вторых, если условий слишком много, таблица решений разрастается (количество комбинаций растёт экспоненциально) и становится трудноуправляемойhabr.com. Например, для 10 двоичных условий теоретически получится 2^10 = 1024 комбинации – такую таблицу ни составить, ни использовать на практике нельзя. В таких случаях лучше применять методы сокращения комбинаций (например, попарное тестирование) или разбить задачу на несколько таблиц по логическим блокам. Таким образом, таблица принятия решений оптимальна для среднего уровня сложности – где условий достаточно, чтобы вручную можно было ошибиться, но не настолько много, чтобы покрыть их все было невозможно.

Пример: допустим, мы имеем правило расчета скидки на страховку автомобиля, зависящее от двух условий: стаж водителя больше 5 лет и был ли он в авариях. Каждый фактор может быть либо Да, либо Нет, итого 4 возможные комбинации. Для каждой комбинации определяется тариф страхования. Например, если стаж маленький и аварии были – тариф максимальный; если стаж маленький, ноаварий не было – тариф чуть ниже; если стаж большой, но были аварии – еще дешевле; если стаж большой и аварий нет – минимальный тариф. Представим эти правила в виде таблицы: в колонках перечислим четыре сочетания условий, в строках – сами условия и итоговое действие (тариф). Получим что-то подобное:

  • Условие 1: Стаж > 5 лет? – Нет / Нет / Да / Да
  • Условие 2: Были аварии? – Да / Нет / Да / Нет
  • Результат (тариф): 200 руб / 100 руб / 50 руб / 10 руб habr.comhabr.com

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

Переход состояний (State Transition Testing)

Описание метода: методика перехода состояний основывается на моделировании поведения системы через конечные состояния и переходы между ними. Для наглядности часто используются диаграммы состояний (state diagrams), где каждый возможный стейт системы изображается как узел, а действия/события рисуются стрелками, переводящими систему из одного состояния в другое. Такая визуализация показывает, как объект или система проходит последовательность этапов во времениtestengineer.ru. Восприятие схемы легче, чем сухого текста, поэтому применение диаграммы переходов состояний помогает быстрее достичь максимального покрытия тестами сложного поведенияtestengineer.ru. State Transition Testing принадлежит к техникам черного ящика, то есть основывается на внешнем наблюдении за реакцией системы на события, без знания внутреннего кодаqaschool.ru.

Когда применять: этот подход эффективен для систем, которые имеют множество различных состояний (режимов работы) и разнообразные события, приводящие к изменению этих состоянийtestengineer.ru. Классические примеры: бизнес-процессы, workflow-сценарии, объекты с жизненным циклом. Например, заказ в интернет-магазине может последовательно находиться в состояниях «создан», «оплачен», «отправлен», «доставлен», «отменён» – и в каждом действует своя логика. Диаграмма переходов позволяет явно перечислить эти состояния и проверить каждое возможное допустимое и недопустимое переключение между ними. Применять технику стоит, когда поведение системы зависит от предыстории (предыдущих шагов). Если функция приложения чисто комбинирует входы и сразу выдаёт выход (без «памяти» о прошлом), то переходы состояний не актуальны. А вот когда результат действия зависит от текущего состояния объекта, нужно убедиться, что мы протестировали все сценарии переходов из каждого состояния по каждому релевантному событию.

Преимущества: техника обеспечивает полноту проверок последовательностей. Она помогает обнаружить ситуации, когда какое-то изменение состояния неправильно обработано или не обработано вовсе. Полезный прием при тест-дизайне – составить таблицу всех возможных пар «состояние X – событие Y» и отметить, что должно произойти. Это выявляет недопустимые переходы: комбинации, которые не должны случаться (например, действие «отправить товар» в состоянии «отменён» заказа)qaschool.ru. Если система не предотвращает такие переходы, это ошибка. Визуальная схема или таблица переходов делает такие пробелы очевидными. Кроме того, работа с моделями состояний структурирует понимание сложной логики и не дает забыть протестировать редкие последовательности действий, например, повторное выполнение операции, выход из нештатного состояния и т.д. Наглядность диаграмм – отдельный плюс, упрощающий общение с разработчиками и аналитиками: на схеме легко показать, где, например, отсутствует нужная стрелка или неправильно определено поведение.

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

Пример: рассмотрим авторизацию пользователя с ограничением на число попыток ввода пароля. Система имеет следующие состояния: пользователь не залогинен (начальное состояние), аккаунт заблокирован, и состояние успешного входа (после удачного ввода пароля). Переходы между ними определяются событием «ввод пары логин/пароль» с двумя исходами – верный или неверный пароль. Изначально пользователь не залогинен и может попытаться войти. Если пароль неверный, число оставшихся попыток уменьшается, и состояние меняется (например, переходим в состояние «Первая неудачная попытка» – хотя внешне система всё еще просто «не залогинила пользователя»). После очередной ошибки система может переходить в состояния «Вторая попытка» и «Третья попытка». После третьей подряд неверной попытки – переход в состояние «Аккаунт заблокирован» (доступ временно закрыт)testengineer.ru. Если же на каком-либо шаге пользователь вводит верный пароль, происходит переход в состояние «Вход выполнен» и одновременно сброс счётчика попыток. С помощью диаграммы это можно изобразить как цепочку: S0:Начальное → (неверный пароль) → S1:1-я ошибка → (неверный) → S2:2-я ошибка → (неверный) → S3:3-я ошибка, аккаунт блокируется → (через 5 минут разблокировки или по запросу админа) → S0 снова; а при верном пароле из любого промежуточного состояния – сразу переход в Вход выполнен. Такой подход гарантирует, что мы проверим все ключевые пути: успешный вход с 1-й попытки, вход со 2-й попытки (после одной ошибки), со 3-й, блокировку аккаунта после 3 ошибок, попытки входа в заблокированном состоянии, разблокировку по времени и т.д. Все эти варианты легко прочитать из диаграммы переходов состояний и затем оформить в тест-кейсы. В результате ни один сценарий (даже нестандартный, например, ввод верного пароля только со 3-го раза) не будет упущен тестированием.

Попарное тестирование (Pairwise Testing, комбинационные методы)

Описание метода: попарное тестирование – техника оптимизации тестовых комбинаций, основанная на комбинаторике. Её суть в том, чтобы при планировании тестов обеспечить покрытие всех возможных пар значений разных параметров, вместо покрытия всех комбинаций этих параметровhabr.com. Иными словами, если у системы есть несколько независимых параметров ввода, мы хотим составить такой набор тестовых случаев, чтобы для любых двух параметров каждая возможная пара значений встретилась хотя бы в одном тесте. Метод pairwise гарантирует, что любое взаимодействие двух факторов будет протестировано хотя бы раз. При этом общее количество тестов значительно меньше, чем при полном переборе всех сочетаний входных параметровhabr.com.

Когда применять: попарное тестирование эффективно, когда нужно протестировать множество параметров с разными значениями, и перебор всех комбинаций приводит к взрыву их числа. В таких ситуациях считается, что большинство дефектов проявляется от взаимодействия не более двух факторов одновременно – более сложные многопараметрические взаимодействия встречаются реже. Поэтому имеет смысл покрыть все пары, а не все сочетания. Например, если нужно проверить форму с 5 выпадающими списками (каждый на несколько вариантов) – полное сочетание вариантов может исчисляться тысячами кейсов, а pairwise позволит обойтись десятками. Технику применяют для тестирования конфигураций систем, совместимости опций, разных окружений, множества настроек и т.д., где прямой перебор нереален.

Преимущества: главное достоинство – радикальное сокращение числа тестов по сравнению с полным перебором, но при этом сохранение покрытия парamentров. Это дает уверенность, что каждая пара опций проверена на совместимость или корректное взаимодействие. Таким образом, pairwise покрывает риск дефектов, основанных на сочетании параметров, но гораздо меньшими силамиhabr.com. Часто экономия колоссальна: добавление каждого нового параметра обычно умножает количество комбинаций, а при попарном подходе рост близок к линейному. Кроме того, существуют инструменты, которые автоматически генерируют наборы тестов по pairwise-алгоритму, что упрощает применение метода на практике.

Ограничения: важно понимать, что попарное тестирование не покрывает сочетания трёх и более параметров – если дефект возникает только при специфической комбинации трех факторов, он может ускользнуть. Метод исходит из гипотезы, что таких сложных дефектов мало либо их можно выявить отдельно целевыми тестами. Поэтому в критичных системах pairwise используют осторожно, дополняя ручным анализом риска. Ещё одна особенность – необходим тщательный отбор параметров и значений: обычно берутся только корректные (позитивные) значения для сочетанийhabr.com. Негативные и граничные случаи проверяются отдельно другими техниками (например, мы сначала удостоверимся, что каждый параметр по отдельности правильно обрабатывает неверные значения). Также генерация pairwise-наборов для очень большого числа параметров может быть нетривиальной без специальных утилит – вручную сложно убедиться, что все пары покрыты без пропусков или дубликатов.

Пример: представим веб-приложение с множеством настроек заказа. Допустим, при оформлении заказа доступны опции: тип товара (например, пирог или чизкейк), размер (маленький, средний, большой), город доставки (Нью-Йорк, Лос-Анджелес, Чикаго), способ получения (доставка курьером или самовывоз), время доставки (немедленно или к определенному времени) и количество товаров в заказе (1, 2 или 3 штуки). Если перемножить все варианты, получим 2×3×3×2×2×3 = 216 комбинацийвозможных заказов. Проверить каждую вручную практически нереально и не нужно. Применяя попарное тестирование, мы стремимся покрыть все пары значений. Например, убедимся, что каждый город проверен с каждым размеромкаждый способ доставки – с каждым временемкаждый тип товара – с каждым количеством и т.д., но не обязательно все одновременно в одном тесте. Существуют онлайн-инструменты, которые генерируют минимальный набор кейсов по pairwise-алгоритму. В нашем примере автоматический расчет дал всего 17 тестовых сценариев, покрывающих все пары значений параметровtestengineer.ru. Это колоссальное сокращение по сравнению с 216 полными комбинациями. В полученных 17 сценариях, к примеру, один тест может покрыть сочетание (пирог, маленький, Нью-Йорк, самовывоз, к указанному времени, 1 штука), другой – (пирог, большой, Чикаго, доставка курьером, немедленно, 3 штуки), и так далее, пока все возможные пары не встретятся хотя бы раз. Таким образом, мы обнаружим большинство проблем взаимодействия настроек (если, скажем, какая-то пара «город + способ доставки» несовместима, тест это вскроет), затратив при этом разумное число проверок. Полный перебор имел бы лишь незначительное дополнение – тройные, четверные сочетания – ценой 199 лишних тестов, что обычно неоправданно.

[task_id id=»20473″]