Программирование7 сентября 2026 г.

Попарное тестирование: как сократить сочетания настроек интерфейса и проверить покрытие пар

Автор
Ненашев А.
На чтение
7 мин
Дата обновления
07.09.2026
Старт:С 24 августа
Срок обучения:1 месяц
Специалист по автоматизированному тестированию
Эта программа включает 12 месяцев обучения и 3 месяца технологической специализации. Вы получите базовые знания, сделаете осознанный выбор карьерной траектории, получите навыки ручного и автоматизированного тестирования, а в итоге найдете работу. На странице курса на Училкин.ru: программа занятий, требования, отзывы и условия записи.
Подробнее
157 000 ₽19 881 ₽
#COURSE##INNER#

Попарное тестирование: как сократить сочетания настроек интерфейса и проверить покрытие пар

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

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

С чего начать: перечислить параметры и убрать бессмысленные комбинации

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

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

ПараметрЗначенияКоличество
Темаlight, dark2
Языкru, en2
Боковая панельcollapsed, expanded2
Подсказкиoff, banner, modal3

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

Почему полный перебор разрастается быстрее, чем кажется

Для полного перебора нужно перемножить количество значений по каждому параметру. В нашем примере это 2 × 2 × 2 × 3 = 24 комбинации. Для учебной задачи число еще терпимое, но это только четыре параметра. Если добавить, например, режим плотности интерфейса с двумя значениями, матрица сразу станет 48. Если затем учесть еще один переключатель, будет уже 96.

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

Попарное покрытие решает именно эту задачу. Оно не отвечает на вопрос «все ли мы проверили», но хорошо отвечает на вопрос «закрыли ли мы все пересечения значений по два». Для экранов с настройками это уже ощутимая экономия по сравнению с полным перебором.

Учебный пример: как сократить 24 комбинации до 6 попарных тестов

Учебный пример. Построим набор тестов для четырех параметров выше. Один из способов получить компактный набор — добиться, чтобы каждая пара значений встретилась хотя бы в одном тесте. Ниже приведен условный набор из 6 сценариев.

ТестТемаЯзыкБоковая панельПодсказки
1lightrucollapsedoff
2darkenexpandedoff
3lightenexpandedbanner
4darkrucollapsedbanner
5lightruexpandedmodal
6darkencollapsedmodal

Почему здесь вообще можно уложиться в 6 тестов? Посмотрим на пару «тема × подсказки». У темы 2 значения, у подсказок 3, значит существует 2 × 3 = 6 разных пар: light-off, light-banner, light-modal, dark-off, dark-banner, dark-modal. Один тест может покрыть только одну такую пару, следовательно, меньше чем 6 тестов быть не может. В этом смысле набор выше не просто короткий, а еще и близок к нижней границе для данного примера.

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

Как убедиться, что покрытие пар действительно есть

У попарного набора есть типичная ловушка: таблица выглядит аккуратно, и команде кажется, что все закрыто. На практике лучше не доверять визуальному впечатлению. Для четырех параметров есть 6 групп пар: тема-язык, тема-панель, тема-подсказки, язык-панель, язык-подсказки, панель-подсказки. Если посчитать варианты внутри каждой группы, получится 4 + 4 + 6 + 4 + 6 + 6 = 30 различных пар значений, которые нужно встретить хотя бы один раз.

Эту проверку можно сделать вручную для маленького примера, но полезнее один раз автоматизировать ее. Ниже код для Python 3.11, который строит множество всех возможных пар и сравнивает его с парами, реально встречающимися в тестах.

from itertools import combinations, product

params = {
    "theme": ["light", "dark"],
    "lang": ["ru", "en"],
    "sidebar": ["collapsed", "expanded"],
    "tips": ["off", "banner", "modal"],
}

suite = [
    {"theme": "light", "lang": "ru", "sidebar": "collapsed", "tips": "off"},
    {"theme": "dark", "lang": "en", "sidebar": "expanded", "tips": "off"},
    {"theme": "light", "lang": "en", "sidebar": "expanded", "tips": "banner"},
    {"theme": "dark", "lang": "ru", "sidebar": "collapsed", "tips": "banner"},
    {"theme": "light", "lang": "ru", "sidebar": "expanded", "tips": "modal"},
    {"theme": "dark", "lang": "en", "sidebar": "collapsed", "tips": "modal"},
]

names = list(params.keys())

def all_pairs(params, names):
    res = set()
    for a, b in combinations(names, 2):
        for va, vb in product(params[a], params[b]):
            res.add((a, va, b, vb))
    return res

def covered_pairs(suite, names):
    res = set()
    for case in suite:
        for a, b in combinations(names, 2):
            res.add((a, case[a], b, case[b]))
    return res

missing = sorted(all_pairs(params, names) - covered_pairs(suite, names))
print(missing)

Для нашего набора результат должен быть пустым списком. Это уже проверяемый итог, а не ощущение. Если список не пуст, вы сразу увидите, какая именно пара пропущена, и сможете добавить один-два теста вместо переделки всей матрицы.

Что попарный набор не поймает: тройные взаимодействия и сценарии за пределами метода

Теперь главный предел метода. Попарное покрытие не гарантирует, что закрыты тройки значений. Возьмем только три параметра из примера: тема, язык и боковая панель. Всего возможных троек здесь 2 × 2 × 2 = 8. Наш набор из 6 тестов включает такие тройки: light-ru-collapsed, dark-en-expanded, light-en-expanded, dark-ru-collapsed, light-ru-expanded, dark-en-collapsed. Значит, как минимум две тройки отсутствуют: light-en-collapsed и dark-ru-expanded.

Почему это важно practically? Представим дефект: в светлой теме английская локаль вместе со свернутой панелью смещает иконки в шапке. Все пары из этой тройки в нашем наборе встречаются по отдельности: light + en есть, light + collapsed есть, en + collapsed тоже есть. Но именно совместное проявление трех условий не проверено. Значит, pairwise не доказывает отсутствие такой ошибки.

Есть и другие классы рисков, которые этот метод не закрывает сам по себе. Он плохо отвечает на вопросы порядка действий: что будет, если сначала сменить язык, потом тему, потом выйти и войти снова. Он не заменяет проверки граничных значений, если в интерфейсе есть числовые диапазоны. Он не охватывает пользовательские потоки через несколько экранов и не показывает, какие состояния особенно рискованны для конкретной бизнес-логики.

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

Если хотите разложить эту тему как часть системного обучения, на официальной странице курса «Специалист по автоматизированному тестированию» у школы Училкин в модуле «Тест-дизайн и тест-аналитика» перечислены попарное тестирование, граничные значения, доменный анализ, таблицы принятия решений и диаграммы переходов состояний. Это полезное соседство тем: оно показывает, чем добирать риски, которые pairwise сам по себе не закрывает.

Курсы

147348
0,0
0 отзывов
Специалист по автоматизированному тестированию
  • С 24 августа
  • 1 месяц
  • в группе с наставником
  • сертификат
157 000 ₽19 881 ₽
Перейти на сайт