Оценка качества тестирования ПО. Часть 2: Классификация критериев тестового покрытия

Предыдущая часть закончилась выводом о необходимости использования метрик для оценки качества тестирования и обещанием классифицировать используемые метрики (они же — критерии тестового покрытия). Обещания надо выполнять.

Майерс безусловно прав, определяя тестирование, как процесс исполнения программы с целью обнаружения ошибок [1]. Хотя с моей точки зрения, позитивные определения тоже имеют право на существование, при попытке их проверки «от противного» как раз и получается определение Майерса.

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

При таком подходе первыми отсеиваются «точечные» ошибки — те, которые проявляются в единственной ситуации (на единственном наборе входных данных), которая ничем не выделяется из аналогичных ситуаций. Например, если функция вычисления площади треугольника по трем сторонам работает правильно везде, кроме (137, 108, 96), то обнаружить такую ошибку можно только при большом везении или при исчерпывающем тестировании, которого не бывает. К тому же, не очень понятно, откуда такая ошибка взялась в программе — разве что по злому умыслу разработчика, но с этим надо бороться по-другому. Значит, остаются более или менее регулярные ошибки, которые проявляются на целом классе ситуаций и могут быть обнаружены сравнительно небольшим набором тестов. Например, для рассмотренной функции вычисления площади треугольника, вполне реально обнаружить ошибки, которые проявляются на всех прямоугольных треугольниках, или на всех равнобедренных треугольниках, поскольку тест для этих особых случаев должен присутствовать в хорошем тестовом наборе.

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

Каковы источники информации о поведении программы?

  1. Исходный код программы

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

    Какова адекватность критериев покрытия, основанных на исходном коде программы?
    С одной стороны, структурные критерии покрытия используют знание реального устройства программы и могут обеспечить хорошее покрытие кода реализации системы. Но с другой стороны хорошее покрытие кода ещё не означает полного соответствия требованиям — какая-то часть функциональности может просто отсутствовать. А плохое покрытие кода не обязательно является недостатком тестового набора — система может обладать какой-либо функциональностью помимо рассмотренной. То есть, структурные критерии покрытия не позволяют делать выводы о качестве проверки требований к программе.

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

  2. Структура входных данных

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

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

  3. Требования

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

    Часто требования формулируются в виде импликации: C => P, где С — условие, а P — предикат, который должен быть выполнен при этом условии. Для критериев покрытия требований используются условия С (предикат P необходим для вынесения вердикта), которые задают ситуацию проверки требования. Эти условия при построении критериев покрытия по требованиям используются аналогично условиям в исходном коде программы, влияющим на поток управления.

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

  4. Модели

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

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

В следующей части будут рассмотрены виды критериев покрытия, используемые в рамках технологии UniTESK [2], и способы достижения высокого уровня покрытия для них.

Литература
1. Майерс Г. Искусство тестирования программ. М.: Финансы и статистика, 1982.
2. UniTESK — индустриальная технология надежного тестирования.

10.11.2007  Метки:   Рубрики: Разработка, Тестирование

Написать комментарий