Прежде всего хотелось бы сказать, что математика помогает привести наши мысли в порядок и эффективно развивает логическое мышление, а это одни из самых необходимых качеств участников разработки программного обеспечения. Говоря о тестировании, то оно в основном касается поведения системы, что ортогонально структурному представлению, общему для разработчиков программного обеспечения. Разница между структурным и поведенческим представлениями заключается в том, что структурное фокусируется на том что представляет собой программное обеспечение, а поведенческое представление учитывает что программное обеспечение делает.  Одна из трудностей тестировщиков заключается в том, что базовая техническая документация или руководство по разработке программного обеспечения обычно пишутся разработчиками и для разработчиков, и в основном акцент делается на структурную, а не на поведенческую информацию. Конечно, как структурные, так и поведенческие части очень важны для тестирования, так как ошибки программирования можно найти в каждой из этих частей. Вот почему мы будем говорить о дискретных математических методах, чтобы показать связь между структурой программы и ее поведением. В своей повседневной работе инженеры по обеспечению качества (QA) программного обеспечения работают с операциями формул, поведением функций и структурами данных. Они всегда контролируют и проверяют постоянно меняющееся состояние систем, поэтому им необходимо иметь алгоритмическое и математическое мышление для понимания логики программного обеспечения. Если разработчик использует математический подход в своей работе, в результате все логические операции будут связаны друг с другом, действия будут следовать логической цепочке, а каждая функция будет рассматриваться структурно. Дискретная математика помогает нам найти оптимальное решение в различных ситуациях. Например, можно найти наиболее подходящий набор тестовых случаев (Test cases), не охватывая все возможные варианты. Более того, дискретная математика помогает нам визуализировать точную часть программного обеспечения, которая была реализована и покрыта тестами. К сожалению, мы не живем в идеальном мире, и ожидаемые реальные результаты применения программного обеспечения и фактические результаты могут отличаться. Итак, главная цель отдела обеспечения качества (QA) — максимально эффективно охватить как можно больше тестовых случаев.

Чтобы показать вам эту концепцию более подробно, мы создали следующую диаграмму Венна с примером, который мы ранее обрисовали в общих чертах: Графы также имеют основополагающее значение для процесса разработки программного обеспечения. Например, используя граф мы можем разложить сложные функции на несколько более мелких частей, что помогает нам более эффективно понимать бизнес-логику. Графы могут быть направленными и ненаправленными, это означает, что мы можем перемещаться от узла к узлу в одном направлении или в обоих направлениях (в случае ориентированного графа), или мы не можем перемещаться от одного узла к другому (если граф является направленным строго в одном направлении) Итак, давайте вернемся к тестированию программного обеспечения и представим, что у нас есть поток некоторого процесса (например, перемещение задачи в какой-то системе отслеживания задач); у нас есть условие некоторой задачи, и мы можем переместить ее на другой этап (ориентированный граф), или мы можем достичь некоторой точки, где мы ничего не можем сделать с сущностью (неориентированный граф). При таком подходе к визуализации мы можем легко собрать набор всех возможных действий, доступных для этой сущности: Давайте продолжим и посмотрим на матрицу смежности, которая может быть построена на основе неориентированного графа. В приведенном ниже примере элементы матрицы смежности указывают, являются ли пары вершин смежными или нет: Теперь представьте, что узлы являются условиями некоторых сущностей, и если мы построим матрицу смежности для этого графа (набора сущностей), мы увидим конечный набор действий, которые мы можем предпринять. Например, изменение статуса с узла «0» на узел «1» доступно, потому что они связаны друг с другом. Но сущность «0» не может быть изменена на стадию «2» или «3», как мы можем видеть из нашей матрицы — в ячейках прописан «ноль». Используя эту матрицу, мы можем исключить ненужные наборы этапов сущности и сократить набор тестовых случаев. Еще одна матрица, которую мы можем использовать для сбора тестовых случаев, — это матрица инцидентности, которая показывает отношения между двумя классами объектов. На следующем рисунке мы видим неориентированный граф и его матрицу инцидентности: «1», «2», «3» и «4» являются узлами (сущностями), «e1», «e2», «e3» «e4» — ребра графа, а матрица иллюстрирует сущности и действия, которые мы можем с ними сделать. С узлом «1» мы можем выполнять действия «e1», «e2» и «e3», но действие «e4» недоступно для узла «1.». Этот метод очень помогает при создании набора тестовых случаев. Представим, что тестировщик получил список сущностей и действий, которые можно проводить с этими сущностями. С помощью этой матрицы он может сократить набор тестовых случаев. Сокращение количества тестов является очень важной частью процесса тестирования программного обеспечения. Тестирование программного обеспечения в значительной степени зависит от сокращения количества тестовых случаев, и при таком подходе охват тестированием и избежание избыточности максимально увеличены. Цель тестировщиков программного обеспечения — охватить продукт, используя эффективные контрольные примеры, которые позволяют тестировать все возможные комбинации действий. Тестировщики могут добиться успеха, прилагая минимальные усилия, используя подходы дискретной математики (алгоритмы), чтобы найти оптимальный набор тестовых случаев и максимизировать эффективность процесса тестирования программного обеспечения. Дискретная математика также помогает нам понять, как на самом деле создается программное обеспечение, потому что все программное обеспечение использует алгоритмы и методы дискретной математики и математической логики. Поэтому, если мы понимаем, как это работает, мы можем найти ошибки или проблемы внутри программы, которые не могут быть обнаружены со стороны пользователя. Давайте рассмотрим пример того, как приложение работает на микросервисной технологии с помощью «Сетей Петри» (динамический граф): Здесь мы видим, что система имеет начальное состояние и должна получить некоторый сигнал, который отправляется из другой службы (появляется маркер). В зависимости от полученного результата должно быть выполнено следующее действие. Таким образом, сеть Петри иллюстрирует динамику всей системы. Если какая-либо проблема существует, мы сможем локализовать дефект быстрее.  Искусственные нейронные сети также основаны на принципах графа. Они имитируют возможности обработки информации нейронами человеческого мозга. Каждая часть нейронной системы основана на графе, который содержит «входные» узлы, «скрытый» слой и «выходные» узлы. Некоторые данные поступают на входной слой, а алгоритмы скрытого слоя обрабатывают эти данные и отправляют результат на выходной этап. Таким образом, нейронная сеть может выполнять действия на основе этих данных. Нейронные сети также состоят из множества похожих графов с другой логикой, поэтому они могут принимать решения на основе входных параметров. Наш последний пример использования дискретной математики в тестировании включает построение процесса тестирования программного обеспечения. В настоящее время существует множество методологий и подходов называемые «millenium testing», которые были разработаны задолго до их фактического использования, начиная с 2000-х годов, когда разработка программного обеспечения начала стремительно развиваться. BDD (Behavior Driven Development) является частью так называемого Millenium тестирования, эта методология является расширением TDD (Test Driven Development). BDD позволяет тестировщикам устанавливать более тесную связь между критериями приемки для данной функции и тестами, используемыми для проверки этой функциональности. BDD может преобразовывать структурированные операторы на естественном языке в исполняемые тесты, тем самым вносит больше ясности и понимания бизнес стороне и стороне разработки, так как они начинают говорить на одном общем языке. Основная структура рабочего процесса BDD также основана на динамическом графе (Petri Net). Как видно из этой структуры, каждый процесс сопровождается другим процессом, и он не может переместиться на следующий этап, пока предыдущий этап не будет завершен. Еще раз, принципы дискретной математики помогают нам понять процесс более эффективно.