Тестирование "белого ящика"

Тестирование “белого ящика”

Тестировщики применяют различные методы тестирования, чтобы выявить проблемы, дефекты и ошибки. Одним из таких методов является тестирование “белого ящика” (white box testing). Этот подход сосредоточен на оценке внутренней структуры и деталей реализации программного обеспечения.

Друзья, поддержите нас вступлением в наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.

Содержание:

Что такое тестирование “белого ящика”?

“Белый ящик” — это метод тестирования, который проверяет внутренний дизайн системы, структуру исходного кода, используемые структуры данных и детали работы. Главная цель этого метода — улучшить дизайн программного обеспечения, поток ввода-вывода, удобство использования и безопасность. Это также называют прозрачным тестированием, структурным тестированием или тестированием «стеклянного ящика».

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

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

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

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

Характеристики

  • Доступ к исходному коду: “Белый ящик” предоставляет доступ к исходному коду, что позволяет проверить отдельные функции и модули.
  • Анализ покрытия кода: С помощью данного метода анализируется покрытие кода и выявляются непроверенные области.
  • Выявление логических ошибок: Этот метод помогает найти логические ошибки, такие как бесконечные циклы и неправильные условные операторы.
  • Оптимизация кода: Он выявляет проблемы с производительностью и области кода, требующие улучшения.
  • Тестирование безопасности: Тестировщики могут идентифицировать уязвимости безопасности благодаря доступу к исходному коду.

Что проверять при тестировании “белого ящика”?

Метод “белого ящика” оценивает исходный код, проверяя следующие параметры:

  • Внутренние уязвимости безопасности.
  • Каждый объект, функцию и оператор исходного кода по отдельности.
  • Функциональность условных циклов.
  • Поломанные, неполные и плохо структурированные пути кода.
  • Поток ввода и вывода.

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

Как проводить тестирование “белого ящика”?

В основном разработчики или тестировщики используют этот метод тестирования в два этапа:

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

Пример тестирования

Теперь мы понимаем, что тестирование “белого ящика” направлено на проверку структуры кода, включая циклы, условные операторы и ветвления решений. Давайте рассмотрим простой пример:

Test (a, b)
{
int n;
if (n % 2 == 0)
{
print("Even number")
}
else
{
print("Odd Number")
}
}

Чтобы проверить этот код, у нас есть два тестовых кейса:

  • Тест 1: n = 25
  • Тест 2: n = 50

В первом тесте, при n = 25, условие if не выполняется. Поэтому выполнение программы переходит в блок else, и выводится соответствующее сообщение. Во втором тесте, при n = 50, условие if выполняется, и выполняется соответствующий код.

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

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

Существует несколько различных техник тестирования “белого ящика”:

1. Покрытие операторов (Statement Coverage)

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

Покрытие операторов определяет, какой процент исходного кода отрабатывает определенный набор тестовых примеров. Формула для покрытия утверждений выглядит следующим образом:

Покрытие операторов = (Количество выполненных операторов / Общее количество операторов) * 100

100%-ное покрытие операторов достигается, когда все исполняемые операторы в коде были выполнены хотя бы один раз в т. ч. выполняются операторы с дефектами.

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

2. Покрытие решений (Decision Coverage/Branch Coverage)

Лучшим примером ветвления в программировании является оператор if. У него есть два ветвления — истинное и ложное. Техника покрытия ветвей обеспечивает выполнение каждой ветви хотя бы один раз.

Покрытие ветвей подразумевает процент ветвей или точек принятия решений, выполненных во время тестирования. Формула для вычисления покрытия ветвей:

Покрытие ветвей = (Количество выполненных ветвей / Общее количество ветвей) * 100%

3. Покрытие условий (Condition Coverage)

Тестирование условий включает проверку отдельных условий на истинные и ложные результаты. Чтобы достичь 100% покрытия условий, необходимо протестировать каждое условие на оба результата. Для n условий у нас будет 2n тестовых скриптов.

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

4. Тестирование множественных условий (Multiple Condition Testing)

Эта техника направлена на тестирование всех возможных комбинаций условий в ветвлении. Рассмотрим следующий код:

if (A || B)
    print C;

Тест-кейсы для приведенного выше кода следующие:

  1. A=TRUE, B=TRUE
  2. A=TRUE, B=FALSE
  3. A=FALSE, B=TRUE
  4. A=FALSE, B=FALSE

В нашем примере два условия — A и B, и у нас четыре тестовых случая. Если бы было три условия, количество тестов возросло бы до восьми.

Для достижения 100% покрытия нам потребуется 2n тестов, что очень исчерпывающе и сложно реализовать.

5. Тестирование путей (Path Testing)

Тестирование путей гарантирует, что все возможные пути в исходном коде выполняются хотя бы один раз. Этот процесс включает создание графа управления потоком (control flow graph, CFG) на основе исходного кода или блок-схемы. Затем определяется цикломатическая сложность, которая отражает количество независимых путей. Тестировщики создают минимальные тестовые случаи для этих независимых путей.

Формула для покрытия путей:

Покрытие путей = (Количество проверенных путей / Общее количество путей в программе) x 100 %

6. Тестирование циклов (Loop Testing)

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

Виды тестирования “белого ящика”

Существуют различные типы тестирования “белого ящика”:

  • Модульное тестирование (Unit Testing): Это первый уровень тестирования программного обеспечения. Оно проверяет каждый модуль приложения, называемый единицей, на корректность. Цель — убедиться, что каждый компонент работает как ожидается.
  • Интеграционное тестирование (Integration Testing): Это следующий этап после модульного тестирования. Оно логически объединяет протестированные модули и проверяет их взаимодействие. Цель — выявить ошибки в взаимодействии компонентов.
  • Тестирование на проникновение (White Box Penetration Testing): Тестировщики имеют полный доступ к исходному коду приложения, а также к данным о сети, IP и серверах, включая пароли и карты. Главная цель тестирования на проникновение — выявить участки исходного кода с уязвимостями безопасности.
  • Мутационное тестирование (White Box Mutation Testing): Как следует из названия, мутационное тестирование основывается на изменениях. Тестировщики вносят небольшие изменения в исходный код, чтобы проверить, выявят ли тестовые случаи ошибки. Если тесты проходят, это указывает на наличие ошибки в коде. Если тесты не проходят, значит, исходный код без ошибок.

Преимущества и недостатки тестирования “белого ящика”

Теперь рассмотрим преимущества и недостатки тестирования “белого ящика”.

Преимущества

  • Комплексность: Тестирование белого ящика является подробным, так как охватывает каждую строку исходного кода.
  • Выявление ошибок: Оно помогает выявить скрытые ошибки, дефекты и уязвимости безопасности. Исправление этих проблем часто приводит к оптимизации кода.
  • Соответствие стандартам: Тестирование гарантирует, что исходный код соответствует стандартам кодирования и оптимизирован по производительности.
  • Раннее тестирование: Даже если графический интерфейс недоступен, тестирование начинается на ранних стадиях жизненного цикла разработки программного обеспечения (SDLC).
  • Автоматизация: Тест-кейсы легко автоматизировать.
  • Прозрачность кода: Доступ к исходному коду помогает определить, какие данные нужны для тестирования.
  • Максимальное покрытие: Тестировщики или разработчики могут создавать тестовые случаи, обеспечивающие максимальное покрытие.

Недостатки

  • Требования к знаниям: Тестирование “белого ящика” требует глубоких знаний программирования для понимания и анализа исходного кода и создания тестовых случаев.
  • Фокус на внутреннем: Оно в основном сосредоточено на внутренних механизмах системы и может упустить внешние проблемы.
  • Время на тестирование: Для крупных приложений требуется много времени на тестирование “белого ящика” из-за длинного исходного кода.
  • Изменения кода: Небольшие изменения в исходном коде требуют повторного написания тестовых случаев.
  • Риски ошибок: Существует высокая вероятность возникновения ошибок на последних стадиях разработки ПО.

Инструменты для тестирования

Вот список некоторых часто используемых инструментов для тестирования “белого ящика”:

  1. Veracode: Предоставляет набор инструментов, которые помогают выявлять и исправлять недостатки в приложениях, разработанных на различных языках программирования, таких как .NET, C++, Java и др. Также можно тестировать настольные и мобильные приложения на безопасность.
  2. EclEmma: Бесплатный инструмент для оценки покрытия кода для Java-приложений. Он предназначен для запуска тестов и анализа результатов в среде Eclipse.
  3. JSUnit.net: Является компонентом JUnit — фреймворка модульного тестирования для Java-приложений. JSUnit — это открытый инструмент для тестирования JavaScript.
  4. NUnit: Фреймворк для тестирования, разработанный на C# для выполнения тестирования на основе данных в приложениях .NET. Поддерживает параллельное выполнение тестов без ручного вмешательства.
  5. CppUnit: Также является компонентом JUnit, как и JSUnit. Он предназначен для модульного тестирования приложений на C++.

Сравнение “белого ящика” и “черного ящика

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

Тестирование “белого ящика”Тестирование “черного ящика”
Требует знания внутренней структуры и работы приложенияНе требует знания внутренней структуры приложения
Позволяет тестировать многие детализированные аспекты приложенияТестируется сквозная функциональность приложения
Тестирование “белого ящика” выполняют разработчики или тестировщики с хорошими знаниями программирования и архитектуры приложенийТестирование “черного ящика” не требует знания программирования и архитектуры приложений
Применимо для нижних уровней тестирования — модульного и интеграционного тестированияПрименимо для более высоких уровней тестирования — системного и приемочного, где приложение тестируется как единое целое

Заключение

Тестирование “белого ящика” требует от тестировщиков глубоких знаний внутренней работы приложения и структуры кода. Благодаря этому методу можно выявить структурные и связанные с безопасностью уязвимости. Основная цель — проверка функциональности и корректности работы приложения на уровне кода.

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

Перевод статьи «White Box Testing».

Оставьте комментарий

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