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

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

Итак, тестирование черного ящика (Black Box). Данный метод также известен как тестирование, основанное на спецификации или тестирование поведения. Данная техника не предполагает доступа, как полного, так и частичного, к системе, т.е. она основывается исключительно на работе с внешним интерфейсом тестируемой программы. То есть мы просто изучаем спецификацию, пишем по ней тестовые сценарии, запускаем приложение и выполняем наши тесты.

Интерфейс приложения. Выполнение позитивного теста
Интерфейс приложения. Выполнение позитивного теста

Тестирование серого ящика (Grey Box) — это комбинация White Box и Black Box методов. Данный метод предполагает частичный доступ к коду проекта. Почерпнуть эту информацию возможно из документации с описанием работы некоторых функций системы, из логов или, например, из корпоративной базы знаний, которая содержит коды ошибок и причины их появления. Все это дает частичное понимание системы, даже без доступа к исходному коду приложения. В нашем примере источником данной информации будет служить небольшое руководство пользователя. Из этого руководства нам становится известно, что доступные значения операций хранятся в списке correct_operations = ['+', '-', '*', '/', '%', '**', 'log']. Это сложение, вычитание, умножение, деление, процент первого числа от второго, возведение первого числа в степень второго и логарифм первого числа по основанию второго. Исходя из этих знаний можно разрабатывать более эффективные тест-кейсы.

Выполнение негативного тест-кейса. Ввод недоступной операции
Выполнение негативного тест-кейса. Ввод недоступной операции

White Box или тестирование белого ящика — метод тестирования ПО, который предполагает полный доступ к коду проекта, т.е. внутренняя структура, устройство и реализация системы известны тестировщику.

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

Путь — это последовательность выполнения операторов, начинающаяся на входе и заканчивающаяся на выходе модуля.

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

Рассмотрим граф потока управления функции calc(first, second, oper) тестируемого калькулятора.

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

Получившийся граф потока управления
Получившийся граф потока управления

Таким образом мы имеем девять маршрутов:

  1. ABJS

  2. ACKS

  3. ADLS

  4. AEMQS

  5. AEMRS

  6. AFNS

  7. AGOS

  8. AHPS

  9. AIS

Далее для каждого из этих путей создаются тест-кейсы, выполнение которых гарантирует покрытие как всех ветвей, так и всех операторов.

Для полного изучения данной темы рекомендую к прочтению книгу Ли Коуплэнда «Практическое Руководство по Тест-Дизайну», и надеюсь, что в этой небольшой статье мне удалось передать суть тестирования ПО методами черного, белого и серого ящиков.

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


  1. mikleh
    22.07.2024 07:34
    +5


  1. lxsmkv
    22.07.2024 07:34
    +2

    Тестирование на основе модели (model based testing) выглядит на первый взгляд как "ну вот же он - путь к полному покрытию!". На практике проблема в том, что, и примите это за эмпирическое правило, количество трудозатрат на полное тестирование приложения минимум равно трудозатратам на его разработку.

    Это свойство происходит из Теоремы Райса: "для любого нетривиального свойства вычислимых функций определение того, вычисляет ли произвольный алгоритм функцию с таким свойством, является алгоритмически неразрешимой задачей" Т.е. выполняет ли функция sum в программе задачу сложения - алгоритмически неразрешимая задача. И мы начинаем понимать, что оказывается наши программные решения вообще никакой полнотой обладать не могут. А если решения не обладают полнотой, то и их тестирование не может обладать полнотой.

    Можно упрарываться по формализму. Но если уж на то пошло, то надо упрываться по формализму в спецификации и брать какой-нибудь TLA+ и покинуть с его помощью вообще плоскость производственной реальности.

    На практике тестирования я нафиг шлю все графы разветвлений условий, кидаю два раза подряд "ß" на промт и программа летит в космос.

    Traceback (most recent call last):
    
      File "main.py", line 60, in run
    
        first = int(input('Укажите первое число: '))
    
    ValueError: invalid literal for int() with base 10: 'ß'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
    
      File "main.py", line 80, in <module>
    
        run()
    
      File "main.py", line 63, in run
    
        first = int(input('Вы ввели некорректные данные. Пожалуйста, введите целое число.'))
    
    ValueError: invalid literal for int() with base 10: 'ß'
    

    Или ввожу 0, 0, % и программа отваливается, потому что процент тоже состоит из деления и этот случай не отлавливается как в случае с делением.

    Traceback (most recent call last):
    
      File "main.py", line 80, in <module>
    
        run()
    
      File "main.py", line 73, in run
    
        result = calc(first, second, op)
    
      File "main.py", line 34, in calc
    
        result = first / second * 100
    
    ZeroDivisionError: division by zero
    

    А еще по юзабилити насылю пригоршню репортов. Например, что за "Попробуйте ещё!" ? Что я должен попробовать ещё? Этих мягких французких булок :)?

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

    Я иногда вспоминаю байку про зеркала в лифтах Нью-Йорка. Люди жаловались на медленные лифты, и решить проблему технически было нецелесообразно. Тогда в лифтах по чьему-то предложению поставили зеркала и жалобы прекратились. Людям стало не так томно ждать. В конце концов решает пользовательский опыт. Если приложением комфортно пользоваться, то пользователи могут многое простить.


    1. andreizhu Автор
      22.07.2024 07:34

      Цель написания данной статьи лишь в том, чтобы на тривиальных примерах продемонстрировать различие между тремя методами тестирования. Благодарю за такой развернутый и подробный комментарий)


  1. VeraKosh
    22.07.2024 07:34

    Книгу вы читали в оригинале?


    1. andreizhu Автор
      22.07.2024 07:34

      Не совсем так, в сети есть перевод на русский язык от Уфимцевой Галины, можно читать в оригинале параллельно с ним


      1. VeraKosh
        22.07.2024 07:34

        Понятно, спасибо, нашла)