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

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

Например, на предприятии, где изготавливались крупногабаритные металлические конструкции из сверхтолстой стали, для контроля геометрии традиционно использовались массивные шаблоны. Их изготовление было дорогим, хранение — неудобным, а применение — трудоёмким.

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

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

Техники тест-дизайна

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

Однако таблицу умножения кто-то придумал. И наши любимые техники — не исключение. Они не являются «изобретением» IT. Это адаптированные математические модели, которые кочевали из одной области знаний в другую, пока не осели в головах тестировщиков. Как они выглядели до того, как стали «инженерными» — и зачем нам вообще знать их историю? Давайте разбираться.

От полного перебора к математическим моделям

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

Предположим, приложение принимает десять параметров, каждый из которых может принимать десять различных значений. Количество возможных комбинаций составит:

10¹⁰ = 10 000 000 000

Даже если выполнение одного теста занимает всего одну секунду, полный перебор потребует более 300 лет непрерывного тестирования.

Поэтому практически сразу после появления сложного программного обеспечения возникла необходимость отвечать не на вопрос «Как проверить всё?», а на вопрос:

«Как выбрать небольшой набор тестов, который с высокой вероятностью обнаружит большинство дефектов?»

Ответ на этот вопрос оказался математическим.

Теория множеств и эквивалентное разбиение

Одной из первых техник тест-дизайна стало эквивалентное разбиение (Equivalence Partitioning).

Предположим, имеется множество всех возможных входных данных:

X

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

Например, поле «Возраст»:

Значение

Ожидаемое поведение

меньше 18

отказ

18–65

допускается

больше 65

особая обработка

Фактически множество входных данных разбивается на три класса эквивалентности.

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

  • отношение эквивалентности;

  • разбиение множества.

Каждый элемент множества принадлежит ровно одному классу, а объединение всех классов полностью покрывает исходное множество.

Эти идеи начали формироваться во второй половине XIX века в работах математиков, занимавшихся развитием теории множеств, включая Richard Dedekind.

В программном тестировании данный подход был систематизирован значительно позже. Одним из первых авторов, подробно описавших его применение, стал Glenford Myers в книге The Art of Software Testing (1979), которая считается одной из наиболее влиятельных работ по тестированию программного обеспечения.

Математический анализ и анализ граничных значений

Следующая широко используемая техника — Boundary Value Analysis.

Практика показывает, что большое количество ошибок возникает не внутри допустимого диапазона значений, а около его границ.

Например:

1…100

типичные тестовые значения будут:

0
1
2
99
100
101

Причина хорошо известна разработчикам:

  • ошибки в операторах < и <=;

  • неправильные проверки диапазонов;

  • переполнение;

  • неверные условия переходов.

С математической точки зрения речь идет об исследовании поведения функции возле границ области определения.

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

Булева алгебра и таблицы решений

Практически любой язык программирования содержит конструкции

AND
OR
NOT

Именно они были впервые формализованы английским математиком George Boole в книге The Laws of Thought (1854).

Булева алгебра стала фундаментом современной цифровой логики.

В тестировании она проявляется прежде всего в двух техниках:

  • Decision Tables;

  • Cause-Effect Graphs.

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

Например:

Пользователь авторизован

Есть права

Доступ

Нет

Нет

Нет

Нет

Да

Нет

Да

Нет

Нет

Да

Да

Да

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

Комбинаторика и Pairwise Testing

Одной из наиболее интересных техник является Pairwise Testing.

Предположим, имеются параметры:

Браузер
Операционная система
Язык
Тип аккаунта
Регион

Полный перебор может потребовать десятки тысяч тестов.

Pairwise предлагает совершенно другой подход.

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

Например:

Chrome + Windows
Chrome + Linux
Firefox + Windows
...

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

Здесь используются методы:

  • комбинаторики;

  • покрывающих массивов (Covering Arrays);

  • ортогональных массивов;

  • теории дизайна экспериментов.

Серия исследований NIST, проведённая с 1999 по 2004 год, показала, что большинство ошибок в программном обеспечении вызываются взаимодействием одного или двух параметров, а количество ошибок, требующих трёх и более параметров, прогрессивно уменьшается

Хотя есть и альтернативное мнение

Статистика и ортогональные массивы

Интересно, что ортогональные массивы появились вовсе не в тестировании.

Они были разработаны индийским статистиком Calyampudi Radhakrishna Rao в середине XX века для планирования статистических экспериментов.

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

Позже этот подход оказался практически идеальным для тестирования программного обеспечения.

По сути, современные инструменты генерации pairwise-наборов используют именно эти математические конструкции.

Теория графов и тестирование переходов состояний

Любую программу можно представить в виде графа:

  • вершины — состояния;

  • рёбра — переходы.

Именно поэтому теория графов стала фундаментом сразу нескольких техник:

  • State Transition Testing;

  • Path Testing;

  • Control Flow Testing.

История начинается ещё в XVIII веке с работы Leonhard Euler о семи мостах Кёнигсберга.

В программной инженерии идеи графов получили новое развитие после публикации статьи Thomas McCabe в 1976 году.

Именно тогда появилась знаменитая цикломатическая сложность:

M = E − N + 2P

где:

  • E — количество рёбер;

  • N — количество вершин;

  • P — количество связанных компонентов графа.

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

Теория вероятностей и статистика

Тестирование практически никогда не может гарантировать отсутствие дефектов.

Оно лишь позволяет увеличить вероятность их обнаружения.

Поэтому многие современные подходы используют вероятностные модели:

  • Risk-Based Testing;

  • статистическое тестирование;

  • выборочное тестирование;

  • моделирование отказов.

Именно здесь используются:

  • теория вероятностей;

  • доверительные интервалы;

  • статистические оценки;

  • распределения случайных величин.

Особенно заметно это в тестировании надёжности и производительности.

Теория информации

Одним из менее очевидных математических оснований тестирования является теория информации, разработанная Claude Shannon.

Интуитивно хороший тест — это тест, который максимально уменьшает неопределённость относительно корректности системы.

Если выполнение теста не даёт новой информации, его ценность невелика.

Именно поэтому при проектировании тестовых наборов стараются избегать избыточности и добиваться максимального покрытия поведения системы минимальным количеством проверок.

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

Сегодня

Современные генераторы тестовых наборов уже используют значительно более сложные математические методы:

  • задачи покрытия множеств (Set Cover);

  • методы оптимизации;

  • SAT-решатели;

  • ограничительное программирование (Constraint Programming).

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

По своей сути это уже задачи дискретной математики и теории алгоритмов, многие из которых относятся к классу NP-трудных.

Заключение

Современный тест-дизайн представляет собой не набор независимых практических приёмов, а совокупность методов, основанных на различных разделах математики.

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

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

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

Комментарии (1)


  1. Dhwtj
    21.07.2026 18:23

    Тесты надо выбирать исходя из

    • Меры устраняемого риска

    • Трудоемкости

    • Ортогональности/избыточности к уже имеющимся тестам

    И большинство критериев из кода не видны.

    Есть эвристики, что ошибки чаще на граничных случаях и т.п. Но это так себе