Измерение качества тестирования встраиваемых приложений с Atollic TrueANALYZER
Введение
В последние годы все большее число разработчиков встраиваемых систем уделяют внимание вопросам тестирования и качества выпускаемых программных продуктов. Такой интерес вполне закономерен, поскольку существует достаточно широкий ряд известных примеров, когда конечные пользователи продукции обнаруживали в ней значительные дефекты уже в процессе эксплуатации. Как выяснилось, эти дефекты обусловлены именно программными ошибками.
Современные встраиваемые системы, как правило, содержат на порядок больше строк кода по сравнению с тем, как это было всего лишь несколько лет назад. Однако с увеличением объема строк кода прямо пропорционально возрастает и число ошибок в этом коде. Так что проблемы риска обнаружения программных ошибок, а также вопросы улучшения тестирования, необходимого для их устранения, становятся важнее, чем когда-либо [1].
Но, помимо внедрения тестирования программного кода в процессе его разработки, также нужно понимать, насколько тщательно это тестирование проведено и насколько можно доверять полученным результатам и гарантировать высокий уровень качества созданного приложения.
Ответом на эти вопросы служит измерение качества тестирования. Но здесь возникает проблема выбора подходящих методик, не только достаточно удобных в понимании и использовании, но и гарантирующих достоверность полученных результатов.
К сожалению, практика показывает, что в большинстве случаев тестирование проводится достаточно неформально, без соблюдения какого-либо набора необходимых инструкций и установленного порядка выполнения. Как следствие, такое тестирование практически не предоставляет никаких количественных показателей, которые могли бы помочь в определении уровня тестового покрытия и, соответственно, уровня качества приложения в целом.
В статье рассматриваются возможности современных инструментов и методологий измерения тестирования, способных предоставить достаточно точную информацию о качестве выполненного исследования, причем проводимого при работе приложений на встраиваемых отладочных платах.
Ключевые аспекты тестирования и необходимость автоматизации
Зачастую источником проблем с качеством продукции в области встраиваемых систем становятся именно неисправности программного обеспечения. Таким образом, производителям следует уделять как можно больше внимания тестированию разрабатываемого ПО. Ведь в значительной мере это помогает компаниям своевременно обеспечивать высокое качество продукции своим клиентам.
Традиционный подход с помощью ручных методов тестирования программного обеспечения уже не успевает за постоянно растущим объемом кода в современных встраиваемых приложениях.
Вот перечень наиболее важных аспектов, которые необходимо учитывать в процессе организации и выполнения тестирования [2].
В большинстве случаев для установления причин возникновения ошибок в коде разработчики пользуются отладчиками. Но прежде чем исправить ошибку, нужно сначала ее найти. При этом важно понимать, что ошибки, обнаруженные до начала тестирования и тем более эксплуатации, обойдутся гораздо дешевле. Поэтому специалисты должны стремиться к тому, чтобы определять и исправлять их как можно раньше, на начальных этапах цикла разработки.
Кроме того, обычно в процессе тестирования выявляется множество самых разнообразных ошибок. Но для получения уверенности в том, что тестирование действительно усовершенствовало программное обеспечение, необходимо также понимать и качество самих проводимых тестовых процедур.
Не меньшее значение имеет и ответ на вопрос, покрывают ли имеющиеся тесты 100% всего исходного кода приложения. Ведь если тестовые процедуры затрагивают лишь незначительную часть общего объема кода, что на практике бывает не так уж нередко, то следует установить, что именно было протестировано в действительности, а что еще предстоит проверить. К сожалению, методы ручного тестирования зачастую не в состоянии дать ответы на эти вопросы [3].
Теперь для эффективного выполнения тестов, лучшего контроля, отчетности и анализа тестовых воздействий становятся востребованными методики и средства уже совершенно другого уровня.
Среди наиболее успешно применяемых средств автоматизации тестирования програм-мных приложений для встраиваемых систем можно назвать пакет Atollic TrueANALYZER. Он содержит набор мощных профессиональных инструментов автоматизации для проведения целевого тестирования встраиваемых систем на отладочных платах. Возможности Atollic TrueANALYZER в полной мере отвечают требованиям, предъявляемым к тестированию современных встраиваемых приложений [4].
В следующих разделах приводится более подробная информация о методиках измерения качества тестирования встраиваемых систем и о путях автоматизации этой работы с помощью подходящих инструментов.
Как измерить качество тестирования
По завершении этапов разработки и тестирования кода внимание смещается к количественному пониманию объема и качества работы, в действительности выполненной во время тестирования.
При подготовке и исполнении наборов тестов нужно учитывать важный момент. Не так уж велика польза от достижения 100%-ного успеха прохождения тестов, если они покрывают лишь незначительную часть кода, в то время как его большая часть остается совершенно не охваченной тестированием и потенциально содержит множество необнаруженных (и, как следствие, неисправленных) ошибок.
Здесь совершенно неправомерно считать, что тестирование успешно завершилось, если исследованию подверглась лишь часть кода программного обеспечения. Так, при применении одного только ручного тестирования, которое не в состоянии охватить полностью весь объем кода, в результате будет получен код, «работающий случайным образом». При проведении более тщательного анализа дальнейшее тестирование участков кода, которые ранее оказались непроверенными, вполне может привести к неуспешным результатам.
Так что при оценке того, достаточно ли тщательно разрабатываемый программный продукт протестирован до выпуска в готовом виде на рынок, критичным становится понимание качества выполняемых тестовых процедур.
Анализ тестового покрытия для измерения качества тестирования
Хорошим средством измерения качества тестов является анализ тестового покрытия исходного кода приложения. В ходе такого анализа исследуется динамический поток выполнения программ.
Чаще всего подобное измерение покрытия кода применяется для исследования того, какие части были протестированы, а какие остались без внимания. Таким образом, эта оценка является прямым показателем качества тестирования [5, 6].
Как будет наглядно пояснено далее, даже самые простые участки кода иногда очень сложно протестировать тщательно. Причина в том, что для обеспечения достаточно скрупулезного тестирования должны быть исполнены все блоки кода, пройдены все ветви и проверены все вложенные выражения всех ветвей условных операторов.
Вместе с тем, поскольку разработчики все больше усложняют свой код, стремительно растет и число возможных подстановок и их комбинаций. То есть тестирование становится все более сложным.
Существует общепринятая формальная классификация методов анализа тестового покрытия, начиная от самых примитивных до наиболее строгих по требованиям к качеству покрытия. Разумеется, более строгие методы анализа покрытия потребуют больше усилий и тестов, но именно благодаря им можно выявить больше потенциальных проблем в коде.
Кстати, среди инженеров — тестировщиков программного обеспечения очень распространено заблуждение, будто достаточно и самого простого анализа, поскольку это не так уж сложно и не требует значительных усилий и времени. Но на самом же деле для определения, действительно ли разрабатываемый продукт протестирован достаточно тщательно и должным образом, зачастую нужны куда более сложные методы анализа.
При оценке затрат в этот момент у руководства проекта возникает мысль, что сложный анализ потребует больших усилий тестировщиков, займет много рабочего времени и не лучшим образом скажется на сроках поставки готовой продукции. Возможно, руководство даже принимает решение вовсе отказаться от подобной идеи.
Но это лишь заблуждение. Ведь существуют специальные инструменты, такие как Atollic TrueANALYZER. Он способен оказать разработчикам и тестировщикам существенную помощь и поддержку. Atollic TrueANALYZER предназначен для выполнения самых строгих видов анализа покрытия кода, которые можно использовать без заметных дополнительных усилий и в автоматическом режиме.
Важность тщательного тестирования сложными методами для критичных систем
Для критичных по безопасности встраиваемых систем качество тестирования до запуска в эксплуатацию имеет решающее, а в ряде случаев даже жизненно важное значение.
В качестве достаточно серьезного примера можно привести стандарт RTCA DO‑178B [7]. Он применяется для разработки критичного по безопасности ПО для летательных аппаратов. Для всех наиболее критичных компонентов авиационного бортового ПО, где программная ошибка может привести к катастрофическим последствиям вплоть до потери воздушного судна и человеческих жизней, этот стандарт требует проводить тестирование по модифицированному методу MC/DC (суть его будет подробно рассмотрена в следующих разделах).
Такой подход достаточно универсален и эффективен и применим не только к авиационно-космической отрасли. Он прекрасно подходит для всех компаний, поставляющих продукцию в крупных объемах. Ведь если с дефектами от программных ошибок столкнется достаточно большое число клиентов, то и исправление этих проблем обойдется весьма недешево.
Данный подход хорош и для разработчиков систем, обновлять которые уже в ходе их практической эксплуатации окажется слишком трудоемким или дорогостоящим процессом (например, критичные к остановке и отключению системы или работающие на значительно удаленных объектах).
Целесообразно применение подхода и во всех случаях, когда поставщики стремятся сохранить свою хорошую репутацию, ведь любые дефекты предлагаемого ими программного обеспечения могут дорого обойтись компании, снижая репутацию в отрасли, степень доверия клиентов к компании и долю на рынке.
Все эти доводы указывают на необходимость применения анализа покрытия кода для выяснения, достаточно ли хорошо протестирован код разработанного ПО. И проводить эти исследования нужно непременно до завершения разработки программных продуктов и уж тем более до поставки клиентам.
Обзор типов анализа покрытия кода
Итак, перейдем к детальному знакомству с применяемыми на практике методами анализа покрытия кода.
В качестве исследуемого участка кода рассмотрим такой пример (рис. 1).
Как видно из рис. 1, даже относительно простые конструкции кода приводят к возникновению множества возможных путей исполнения. В данном случае имеем три блока кода. Красный блок исполняется всегда. Зеленый блок исполняется в зависимости от некоторых условий, выполняемых или нет при обработке выражения IF. Синий блок, опять же, исполняется всегда.
Структуру данного исследуемого участка кода можно представить в виде диаграммы потока выполнения (рис. 1, справа). Из диаграммы видно, что существует два возможных пути выполнения кода: один из красного блока сразу в синий, и второй с прохождением зеленого блока. Выбор того или иного пути осуществляется при обработке выражения IF.
Рассмотрим, как действуют наиболее распространенные методы анализа кода, на примере этого конкретного участка кода.
Метод покрытия по выражениям или блокам кода
Метод предоставляет только возможность определить, какое количество выражений языка C или блоков кода было выполнено на протяжении данного сеанса тестирования (поскольку каждый блок кода имеет фиксированный набор выражений, суть у этих двух измерений одна и та же). Принцип метода показан на рис. 2.
Причем метод покрытия по выражениям или блокам кода не дает возможности оценивать, каким образом ветви, встречающиеся в потоке выполнения, влияют на то, какие выражения или блоки кода будут выполнены.
Этот вид анализа покрытия кода является наименее строгим, так как способен лишь определять, какие части кода были выполнены, но без учета сопутствующих обстоятельств. Как правило, для обеспечения приемлемого качества тестирования применение только данного метода не будет достаточным.
Метод покрытия функций кода
Метод позволяет оценить, какие именно С‑функции были вызваны на протяжении данного сеанса тестирования и какую часть от общего числа С‑функций, содержащихся в коде, они составляют. Суть метода показана на рис. 3.
Тем не менее этот метод не позволяет определить, какие именно вызовы функций были выполнены фактически, а также оценивать качество тестирования самих функций.
Метод покрытия функций кода также не относится к числу строгих, и в большинстве случаев его применения недостаточно, чтобы претендовать на высокий уровень качества тестирования.
Метод покрытия вызовов функций
Метод позволяет оценить, какие вызовы функций фактически были выполнены на протяжении данного сеанса тестирования, а также понять, каким образом эти вызовы осуществлялись (рис. 4).
Конечно, метод покрытия вызовов функций не следует причислять к числу наиболее прогрессивных видов анализа покрытия кода. Тем не менее он является достаточно хорошим средством оценки числа выполненных вызовов функций.
Метод покрытия ветвей кода
Метод позволяет оценить, все ли ветви из числа возможных по ходу выполнения были пройдены в процессе тестирования.
Основное требование метода в том, чтобы исследуемый участок кода был выполнен достаточное число раз для прохождения всех возможных альтернативных ветвей в пути выполнения этого кода. Соответственно, при обходе всех ветвей выполняются и все используемые в них блоки кода.
Результатами исследуемого выражения, выделенного на рис. 5 желтым цветом, являются логические значения TRUE (1) и FALSE (0). Однако при этом остается неизвестным, какие результаты вложенных выражений повлияли на принятие решения о выборе той или иной ветви в пути выполнения кода. Таким образом, для получения результатов TRUE и FALSE данное выражение должно быть протестировано по меньшей мере два раза.
Модифицированный метод покрытия по ветвям/условиям (MC/DC)
Модифицированный метод покрытия по ветвям/условиям (Modified Condition/Decision Coverage, или MC/DC) является очень качественным средством анализа покрытия исходного программного кода.
Он широко применяется для приложений, в которых необходимо обеспечить наиболее высокий уровень надежности.
По сути, это усовершенствованный метод покрытия ветвей с дополнительным требованием: все вложенные выражения, задействованные в принятии комплексного решения по конкретной ветви (например, в случае составного выражения IF), должны оказывать влияние на принятие этого решения вне зависимости друг от друга.
Это означает, что исследуемый участок кода должен быть выполнен большее число раз, чем при применении менее строгих методов анализа. Причина в том, что необходимо обрабатывать различные комбинации входных значений, за счет которых вложенные выражения влияют на прохождение кода по различным путям выполнения.
В приведенном примере (рис. 6) выражение проверяется таким образом, что учитываются все результаты обработки вложенных выражений (a, b, c) во всех ветвях кода. При этом каждое из вложенных выражений всякий раз оказывает влияние на ход выполнения кода вне зависимости от других вложенных выражений. Все блоки кода будут выполнены, и все ветви обойдены. Так что данное выражение должно быть протестировано по меньшей мере четыре раза.
Опять же, число возможных путей выполнения программы в значительной степени зависит от результатов обработки условных выражений. И разумеется, этот факт довольно сложно адекватно учитывать при ручном тестировании.
Модифицированный метод покрытия по ветвям/условиям (MC/DC) — чрезвычайно строгий тип анализа тестового покрытия кода. И на практике он широко применяется для оценки качества исследования самых разнообразных программных приложений, критичных по безопасности. Так, требование к обеспечению качества по методу MC/DC распространено при тестировании ПО для бортовых систем управления в летательных аппаратах.
Проблема выбора инструментов для измерения качества тестирования
До сих пор было достаточно трудно подобрать инструменты для измерения качества тестирования программного обеспечения, подходящие для встраиваемых систем. Те немногие инструменты, которые существовали, имели одно или несколько из следующих ограничений:
- Поддержка только слабых типов анализа кодового покрытия.
- Тестирование возможно только на симуляторах на базе настольных персональных компьютеров, но не на целевых встраиваемых отладочных платах.
- Высокая стоимость инструментов.
- Сложность использования.
- Отсутствие возможности интегрирования с другими инструментами разработки встраиваемых систем.
Преимущества Atollic TrueANALYZER
Теперь пришло время новых, усовершенствованных средств, среди которых можно назвать Atollic TrueANALYZER. Он поддерживает широкий диапазон всевозможных типов анализа покрытия кода, от слабых до самых строгих, что весьма важно в случае разработки ПО для критичных встраиваемых систем. Кроме того, он превосходно интегрируется с другими инструментами разработчиков встраиваемых приложений, что делает их работу легче, удобнее и эффективнее. Все это, разумеется, положительно влияет на качество создаваемых программных продуктов.
Одно из наиболее существенных преимуществ Atollic TrueANALYZER — проведение анализа непосредственно на целевых встраиваемых системах. Этот достаточно мощный инструмент очень прост в использовании, к тому же поддерживает широкий ряд полезных функциональных возможностей для измерения качества тестирования кода:
- метод покрытия по выражениям или блокам кода;
- метод покрытия функций кода;
- метод покрытия вызовов функций;
- метод покрытия ветвей кода;
- модифицированный метод покрытия по ветвям/условиям (MC/DC).
На рис. 7 показано, как Atollic TrueANALYZER сочетает применение всех этих методов для достижения лучших результатов и для наиболее эффективного измерения качества тестового покрытия.
Кроме того, некоторые инструменты покрытия кода используют для анализа данные буферизации, полученные в ходе трассировки JTAG-инструкций.
Однако в ходе такой трассировки, даже в случаях кратковременного запуска выполнения, генерируется огромное количество данных. Так что при их применении, как правило, могут быть записаны данные лишь о считанных секундах функционирования исследуемых систем. Нередко это означает, что применять подобные инструменты для полномасштабного тестирования не представляется возможным.
Вот несколько типичных примеров. Испытания микроволновой печи, пока она размораживает курицу. Исследование поведения какого-либо человеко-машинного интерфейса, который требует многократного взаимодействия с пользователем. Управление некоторым подвижным механизмом, передвигающимся очень медленно и в течение длительного периода времени.
Конечно, для таких случаев необходимы качественно другие инструменты.
Atollic TrueANALYZER использует относительно небольшой объем памяти, который не возрастает с увеличением времени выполнения тестов, и поэтому данный инструмент успешно используется для исследований, требующих нескольких минут или даже часов выполнения.
Принципы работы с Atollic TrueANALYZER
Работа с Atollic TrueANALYZER выполняется следующим образом (рис. 8). Инструмент подключается к целевой плате в режиме JTAG-отладки и взаимодействует с ней точно так же, как и в процессе системного программирования. Исследуемое встраиваемое приложение запускается непосредственно на целевой плате, и вся собранная информация о покрытии кода записывается для дальнейшего изучения и количественного анализа.
Тот факт, что анализ покрытия кода выполняется как приложение, запускаемое на целевой системе, критически важен. Ведь нет никакой гарантии, что тесты, реализуемые на ПК, в среде симуляции, будут достоверным образом эмулировать взаимодействие целевой системы со всеми внешними факторами, встречающимися в реальности. А значит, один и тот же тест, успешно пройденный на симуляторе, может завершиться неудачей при запуске на целевой отладочной плате.
Таким образом, однозначно достоверное тестирование возможно лишь на целевых системах, со всеми их потоками ввода/вывода, включая интерфейс пользователя, пакеты передачи данных, показания датчиков и сенсоров и т. д.
В процессе работы возможно привлечение оператора или внешней системы, предоставляющей стимулирующие воздействия для того, чтобы код тестируемого приложения проходил различные пути выполнения.
Применяя такой подход, Atollic TrueANALYZER имеет значительное преимущество по сравнению с другими средствами тестирования, доступными в настоящее время для разработчиков встраиваемых систем.
Отображение результатов измерения тестирования
По завершении очередного сеанса тестирования Atollic TrueANALYZER загружает полученную информацию о покрытии (качестве тестирования) кода исследуемого приложения и отображает результаты своей работы на трех доступных уровнях абстракции:
- Общее покрытие в пределах всего разрабатываемого проекта.
- Покрытие по каждой из C‑функций.
- Покрытие по каждой из строк кода.
В первых двух случаях результаты представлены в виде таблиц, а в последнем — информация о покрытии отображается с помощью цветовой подсветки исходного кода в редакторе (рис. 9).
В секции Coverage result > Summary приводится общая информация об измерении покрытия всего проекта всеми поддерживаемыми методами: покрытия функций (Function coverage), блоков кода (Block coverage), ветвей (Branch coverage), вызовов функций (Call coverage) и по методу MC/DC. Значения представлены в процентном и абсолютном выражении.
Ниже следует таблица результатов измерений покрытия по C‑функциям. Указываются имя функции (Function Name) и значения, полученные при расчете по каждому из методов.
При нажатии в этом окне на имени конкретной функции, в нижней панели открывается соответствующий файл исходного кода и в редакторе отображается исходный код данной функции. Для наглядности строки протестированного и невыполненного кода имеют разную цветовую подсветку.
Но такой вид отображения показателей измерения качества тестирования предоставляет только информацию о достигнутом уровне качества тестирования, а это еще не все.
Также Atollic TrueANALYZER позволяет наглядно увидеть, где и почему тестовые процедуры не обеспечивают достаточное покрытие. Таким образом поддерживается хорошая возможность отлаживать и совершенствовать тестовые случаи, чтобы они покрывали больше частей разрабатываемого кода.
В частности, в результате измерений по методу MC/DC отображаются все решения, принятые по всем ветвям для каждой из C‑функций, а также информация о покрытии для каждого из условий в этих ветвях (рис. 10).
В таблице для каждой записи приводится порядковый номер (No.), принятое решение (Decision), условие принятия решения (Condition), соответствующее выражение (Expression). В колонке Covered указан признак покрытия конкретного варианта, то есть все ли условия в данной ветви принятия решений удовлетворяют требованиям покрытия по методу MC/DC.
Кроме того, для всех составных решений по ветвям отображается таблица истинностей, так что можно наглядно видеть, какие комбинации условий не обработаны и, соответственно, не сыграли в пользу улучшения тестового покрытия.
Здесь указываются порядковый номер каждого тестового случая (Case No.), общий результат его обработки (Result), а также результаты обработки каждого из вложенных условий (в примере C0, C1 и C2).
Другими словами, средства просмотра результатов измерений по методу MC/DC выступают в качестве отладчика тестовых случаев, позволяя разработчикам быстро понять, почему имеющийся набор тестовых случаев не обеспечивает достаточно высокое покрытие.
Следует дополнить, что совместное использование информации с обеих форм (рис. 9 и 10) позволяет получить ясную однозначную картину того, какой уровень тестового покрытия (а значит, и уровень качества тестирования) достигнут, а также какие конкретные тестовые случаи обработаны не лучшим образом и по какой причине.
Подводя итоги, можно утверждать, что использование Atollic TrueANALYZER позволяет разработчикам измерять качество тестирования и проводить отладку процедур тестирования, а значит, и находить больше ошибок в программном коде до момента передачи готового ПО в эксплуатацию клиентам. Это хорошее средство для точного определения уровня достигнутого качества тестирования и, следовательно, для уверенности в качестве предоставляемых программных продуктов.
Заключение
С каждым годом программное обеспечение для встраиваемых систем становится все более объемным и сложным. Увеличивается необходимость в применении улучшенных методов тестирования и отображения результатов, которые способны оказать существенную помощь в создании целесообразных наборов тестов для обнаружения и исправления ошибок и ненадлежащей реализации.
Нередко команды разработчиков пренебрегают необходимостью проведения количественных измерений качества выполняемого тестирования, поскольку ошибочно считают этот этап работ слишком трудоемким или затруднительным для их понимания.
Однако инструмент Atollic TrueANALYZER является простым и удобным в ежедневном применении для большинства разработчиков встраиваемых систем. Он эффективно справляется с задачей измерения качества тестирования, проводимого непосредственно на отладочных целевых платах.
Возможности Atollic TrueANALYZER позволяют применять достаточно высокую степень строгости оценки на уровне программных приложений для бортовых систем управления полетами. Соответственно, значительно повышается и общий уровень качества и надежности производимых и поставляемых программных приложений, что становится определяющим фактором для гарантированной успешной разработки критичных по безопасности встраиваемых систем.
- Сергеева А. Возможности статического анализатора Atollic TrueINSPECTOR для повышения качества встраиваемых приложений // Компоненты и технологии. 2015. № 4.
- Сергеева А. Тестирование работоспособности промышленного компьютера // Компоненты и технологии. 2014. № 2.
- Сергеева А. Автоматизация модульного тестирования с Atollic TrueVERIFIER для повышения качества встраиваемых приложений // Компоненты и технологии. 2015. № 5.
- Об инструменте Atollic TrueANALYZER. atollic.com/trueanalyzer /ссылка утрачена/
- Сергеева А. Применение реинжиниринга при проектировании встраиваемых систем. Часть 1 // Компоненты и технологии. 2014. № 9.
- Сергеева А. Применение реинжиниринга при проектировании встраиваемых систем. Часть 2 // Компоненты и технологии. 2014. № 10.
- О стандарте RTCA.