Покрытие кода - Code coverage

В Информатика, тестовое покрытие мера, используемая для описания степени, в которой исходный код из программа выполняется, когда конкретный тестирование бежит. Программа с высоким тестовым покрытием, измеряемым в процентах, во время тестирования выполнила больше исходного кода, что говорит о том, что у нее меньше шансов содержать необнаруженные программные ошибки по сравнению с программой с низким тестовым покрытием.[1][2] Для расчета тестового покрытия можно использовать множество различных показателей; некоторые из самых основных - это процентное соотношение программы подпрограммы и процент программы заявления вызывается во время выполнения набора тестов.

Тестовое покрытие было одним из первых методов, изобретенных для систематического тестирование программного обеспечения. Первое опубликованное упоминание было сделано Миллером и Мэлони в Коммуникации ACM в 1963 г.[3]

Критерии покрытия

Чтобы измерить, какой процент кода был использован тестирование, один или больше критерии покрытия используются. Критерии покрытия обычно определяются как правила или требования, которым должен удовлетворять набор тестов.[4]

Основные критерии покрытия

Существует ряд критериев покрытия, основными из которых являются:[5]

  • Охват функций - имеет каждую функцию (или подпрограмма ) в программе назывался?
  • Покрытие заявления - есть каждый утверждение в программе было выполнено?
  • Покрытие края - есть все край в График потока управления был казнен?
  • Покрытие филиала - имеет каждую ветку (также называемую DD-путь ) каждой структуры управления (например, в если и дело заявления ) казнили? Например, учитывая если утверждение, были ли выполнены как истинная, так и ложная ветви? Это подмножество покрытие краев.
  • Покрытие условий (или покрытие предиката) - каждое логическое подвыражение оценивается как истинное и ложное?

Например, рассмотрим следующую функцию C:

int фу (int Икс, int у){    int z = 0;    если ((Икс > 0) && (у > 0))    {        z = Икс;    }    возвращаться z;}

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

  • Если во время этого выполнения функция 'foo' вызывалась хотя бы один раз, то покрытие функции для этой функции выполняется.
  • Покрытие заявления для этой функции будет выполнено, если она была вызвана, например в качестве foo (1,1), как и в этом случае, выполняется каждая строка функции, включая г = х;.
  • Вызов тестов foo (1,1) и foo (0,1) удовлетворит покрытие филиала потому что в первом случае оба если условия соблюдены и г = х; выполняется, а во втором случае первое условие (х> 0) не удовлетворяется, что препятствует выполнению г = х;.
  • Покрытие условий может быть удовлетворен тестами, которые вызывают foo (1,0) и foo (0,1). Это необходимо, потому что в первых случаях (х> 0) оценивает истинный, а во втором - ложный. В то же время первый случай делает (у> 0) ложный, а второй делает это истинный.

Покрытие условий не обязательно подразумевает покрытие ветвей. Например, рассмотрим следующий фрагмент кода:

если а и б тогда

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

  • а = правда, b = ложь
  • а = ложь, b = верно

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

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

Измененное условие / покрытие решения

Комбинация покрытия функций и покрытия ветвей иногда также называется покрытие решений. Этот критерий требует, чтобы каждая точка входа и выхода в программе вызывалась хотя бы один раз, и каждое решение в программе принималось по всем возможным результатам хотя бы один раз. В этом контексте решение - это логическое выражение, состоящее из условий и нуля или более логических операторов. Это определение не то же самое, что и покрытие ветвей,[6] однако некоторые действительно используют термин покрытие решений как синоним покрытие филиала.[7]

Покрытие условий / решений требует, чтобы выполнялись и решения, и условия. Однако для критически важный для безопасности приложений (например, для программного обеспечения авионики) часто требуется, чтобы модифицированное покрытие условий / решений (MC / DC) быть довольным. Этот критерий расширяет критерии условия / решения с требованиями, чтобы каждое условие независимо влияло на результат решения. Например, рассмотрим следующий код:

если (а или же б) и c тогда

Критериям условия / решения будет соответствовать следующий набор тестов:

  • a = верно, b = верно, c = верно
  • а = ложь, б = ложь, с = ложь

Однако указанный выше набор тестов не будет удовлетворять модифицированному покрытию условий / решений, поскольку в первом тесте значение «b», а во втором тесте значение «c» не будет влиять на результат. Итак, для соответствия MC / DC необходим следующий набор тестов:

  • а = ложь, б = правда, с =ложный
  • а = ложь, б =истинный, c =истинный
  • а =ложный, b =ложный, c = истина
  • а =истинный, b = ложь, c =истинный

Покрытие множественных условий

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

  • а = ложь, б = ложь, с = ложь
  • а = ложь, б = ложь, с = правда
  • а = ложь, б = истина, с = ложь
  • a = ложь, b = правда, c = правда
  • а = истина, б = ложь, с = ложь
  • а = правда, б = ложь, с = правда
  • а = верно, б = верно, с = ложно
  • a = верно, b = верно, c = верно

Охват значения параметра

Охват значения параметра (PVC) требует, чтобы в методе, принимающем параметры, учитывались все общие значения этих параметров. Идея состоит в том, что проверяются все общие возможные значения параметра.[8] Например, общие значения для строки: 1) null, 2) пусто, 3) пробел (пробел, табуляция, новая строка), 4) допустимая строка, 5) недопустимая строка, 6) однобайтовая строка, 7) двухбайтовая строка. байтовая строка. Также может оказаться целесообразным использовать очень длинные строки. Отсутствие проверки каждого возможного значения параметра может привести к ошибке. Тестирование только одного из них может привести к 100% покрытию кода, поскольку покрывается каждая строка, но поскольку тестируется только один из семи вариантов, ПВХ составляет только 14,2%.

Другие критерии покрытия

Есть и другие критерии покрытия, которые используются реже:

  • Последовательность и скачок линейного кода (LCSAJ) покрытие a.k.a. Покрытие JJ-Path - все ли пути LCSAJ / JJ были выполнены?[9]
  • Покрытие пути - Были ли выполнены все возможные маршруты через данную часть кода?
  • Охват въезда / выезда - Были ли выполнены все возможные вызовы и возврат функции?
  • Покрытие петли - Все возможные циклы выполнялись ноль раз, один раз и более одного раза?
  • Государственное покрытие - Имеет каждое государство в конечный автомат были достигнуты и исследованы?
  • Покрытие потока данных - Было ли достигнуто и изучено определение каждой переменной и ее использование?[10]

Безопасность критически важна или же надежный часто требуется, чтобы приложения продемонстрировали 100% покрытие тестами. ECSS -Стандарт E-ST-40C требует 100% покрытия заявлений и решений для двух из четырех различных уровней критичности; для других значения целевого охвата являются предметом переговоров между поставщиком и заказчиком.[11]Однако установление конкретных целевых значений - и, в частности, 100% - критиковалось практиками по разным причинам (см.[12])Мартин Фаулер пишет: «Я бы с подозрением относился к чему-то вроде 100% - это пахло бы тем, что кто-то пишет тесты, чтобы сделать счастливыми цифры покрытия, но не думает о том, что они делают».[13]

Некоторые из вышеперечисленных критериев покрытия связаны. Например, покрытие пути подразумевает покрытие решения, утверждения и входа / выхода. Покрытие решений подразумевает покрытие операторов, потому что каждое утверждение является частью ветви.

Полное покрытие пути описанного выше типа обычно непрактично или невозможно. Любой модуль с последовательностью решения в нем могут иметь до пути внутри него; конструкции цикла могут приводить к бесконечному количеству путей. Многие пути также могут быть недопустимыми, поскольку в тестируемую программу нет ввода, который может вызвать выполнение этого конкретного пути. Однако было доказано, что универсальный алгоритм для определения невозможных путей невозможен (такой алгоритм может быть использован для решения проблема остановки ).[14] Базовое тестирование пути это, например, метод достижения полного покрытия ветвей без достижения полного покрытия пути.[15]

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

На практике

Целевое программное обеспечение создается со специальными опциями или библиотеками и запускается в контролируемой среде, чтобы сопоставить каждую выполняемую функцию с функциональными точками в исходном коде. Это позволяет тестировать части целевого программного обеспечения, которые редко или никогда не используются в нормальных условиях, и помогает удостовериться, что самые важные условия (функциональные точки) были протестированы. Полученный результат затем анализируется, чтобы увидеть, какие области кода не были проверены, и тесты обновляются, чтобы включить эти области по мере необходимости. В сочетании с другими методами покрытия тестами цель состоит в разработке строгого, но управляемого набора регрессионных тестов.

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

  • Каковы требования к покрытию для сертификации конечного продукта, и если да, то какой уровень покрытия требуется? Типичный уровень строгости: утверждение, ветвь / решение, Покрытие измененных условий / решений (MC / DC), LCSAJ (Последовательность и скачок линейного кода )
  • Будет ли покрытие измеряться с помощью тестов, которые подтверждают требования, предъявляемые к тестируемой системе (DO-178B )?
  • Можно ли напрямую отследить созданный объектный код до операторов исходного кода? Определенные сертификаты (например, DO-178B уровня A) требуют покрытия на уровне сборки, если это не так: «Затем необходимо выполнить дополнительную проверку объектного кода, чтобы установить правильность таких сгенерированных кодовых последовательностей» (DO-178B ) пункт 6.4.4.2.[16]

Авторы программного обеспечения могут просматривать результаты покрытия тестами, чтобы разработать дополнительные тесты и наборы входных данных или конфигурации для увеличения покрытия жизненно важных функций. Две распространенные формы тестового покрытия - это покрытие операторов (или строк) и покрытие ветвей (или границ). Покрытие строк сообщает о следах выполнения тестирования, в том числе о том, какие строки кода были выполнены для завершения теста. Пограничное покрытие сообщает, какие ветви или точки принятия решения по коду были выполнены для завершения теста. Оба они сообщают метрику покрытия, измеряемую в процентах. Смысл этого зависит от того, какая форма (формы) покрытия использовалась, так как 67% покрытие филиалов является более полным, чем покрытие 67% отчетов.

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

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

Большинство профессиональных разработчиков программного обеспечения используют покрытие C1 и C2. C1 означает покрытие операторов, а C2 - покрытие ветвей или условий. С помощью комбинации C1 и C2 можно охватить большинство операторов базой кода. Покрытие операторов также будет охватывать покрытие функций с входом и выходом, циклом, путем, потоком состояний, потоком управления и покрытием потока данных. С помощью этих методов можно достичь почти 100% покрытия кода в большинстве программных проектов.[17]

Использование в промышленности

Охват испытаний является одним из факторов, учитываемых при сертификации оборудования авионики по безопасности. Руководящие принципы, согласно которым авиационное оборудование сертифицировано Федеральная авиационная администрация (FAA) задокументировано в DO-178B[16] и DO-178C.[18]

Охват тестирования также является требованием части 6 стандарта безопасности автомобилей. ISO 26262 Дорожные транспортные средства - функциональная безопасность.[19]

Смотрите также

Рекомендации

  1. ^ Брейдер, Ларри; Хилликер, Хауи; Уиллс, Алан (2 марта 2013 г.). «Глава 2 Модульное тестирование: внутреннее тестирование». Тестирование для непрерывной доставки с Visual Studio 2012. Microsoft. п. 30. ISBN  1621140180. Получено 16 июн 2016.
  2. ^ Уильямс, Лори; Смит, Бен; Хекман, Сара. «Тестовое покрытие с EclEmma». Открытый семинар по разработке программного обеспечения. Государственный университет Северной Каролины. Архивировано из оригинал 14 марта 2016 г.. Получено 16 июн 2016.
  3. ^ Джоан Миллер, Клиффорд Дж. Мэлони (февраль 1963 г.). «Систематический анализ ошибок цифровых компьютерных программ». Коммуникации ACM. Нью-Йорк, Нью-Йорк, США: ACM. 6 (2): 58–63. Дои:10.1145/366246.366248. ISSN  0001-0782.
  4. ^ Пол Амманн, Джефф Оффатт (2013). Введение в тестирование программного обеспечения. Издательство Кембриджского университета.
  5. ^ Гленфорд Дж. Майерс (2004). Искусство тестирования программного обеспечения, 2-е издание. Вайли. ISBN  0-471-46912-2.
  6. ^ Документ с изложением позиции CAST-10 (июнь 2002 г.). Что такое «решение» в применении модифицированных условий / покрытия решений (MC / DC) и покрытия решений (DC)?
  7. ^ MathWorks. Типы покрытия модели.
  8. ^ Модульное тестирование с охватом значений параметров (PVC)
  9. ^ М. Р. Вудворд, М. А. Хеннелл, «О взаимосвязи между двумя критериями покрытия потока управления: всеми JJ-путями и MCDC», Информационные и программные технологии 48 (2006), стр. 433-440
  10. ^ Тин Су, Кэ Ву, Вэйкай Мяо, Гэгуан Пу, Цзифэн Хэ, Ютин Чен и Чжендун Су. «Обзор тестирования потока данных». ACM Comput. Surv. 50, 1, статья 5 (март 2017 г.), 35 стр.
  11. ^ ECSS-E-ST-40C: Космическая техника - Программное обеспечение. Секретариат ECSS, ESA-ESTEC. Март 2009 г.
  12. ^ К. Праузе, Дж. Вернер, К. Хорниг, С. Бозекер, М. Курманн (2017): Является ли 100% покрытие тестами разумным требованием? Уроки, извлеченные из проекта космического программного обеспечения. В: ПРОФЕС 2017. Springer. Последний доступ: 17.11.2017
  13. ^ Блог Мартина Фаулера: TestCoverage. Последний доступ: 17.11.2017
  14. ^ Дорф, Ричард К .: Компьютеры, разработка программного обеспечения и цифровые устройства, Глава 12, стр. 15. CRC Press, 2006. ISBN  0-8493-7340-9, ISBN  978-0-8493-7340-4; через Поиск книг Google
  15. ^ Ю.Н. Срикант; Прити Шанкар (2002). Справочник по проектированию компиляторов: оптимизация и создание машинного кода. CRC Press. п. 249. ISBN  978-1-4200-4057-9.
  16. ^ а б RTCA /DO-178B, Вопросы программного обеспечения при сертификации бортовых систем и оборудования, Радиотехническая комиссия по аэронавтике, 1 декабря 1992 г.
  17. ^ Борис Бейзер (2009). Методики тестирования программного обеспечения, 2-е издание. Dreamtech press. ISBN  978-81-7722-260-9.
  18. ^ RTCA /DO-178C, Вопросы программного обеспечения при сертификации бортовых систем и оборудования, Радиотехническая комиссия по аэронавтике, Январь 2012 г.
  19. ^ ISO 26262-6: 2011 (en) Транспорт дорожный - Функциональная безопасность - Часть 6: Разработка продукта на уровне программного обеспечения. Международная организация по стандартизации.