Степень покрытия программного кода тестами - важный количественный показатель, позволяющий оценить качество системы тестов, а в некоторых случаях - и качество тестируемой программной системы. Данные о степени покрытия помещаются в отчеты о покрытии, которые генерируются при выполнении тестов инструментальными средствами, поддерживающими процесс тестирования, т.е. по сути, генерируются средой тестирования (Рис 13.1). Формат отчетов о покрытии обычно единый внутри проекта или нескольких проектов и часто зависит от особенностей инструментальных средств тестирования.
В отчете о покрытии в стандартизированной форме указываются участки программного кода тестируемой системы (или ее части), которые не были выполнены во время выполнения тестовых примеров, т.е. не были покрыты тестами. Причины непокрытия анализируются тестировщиками, по результатам анализа составляются отчеты о проблемах и запросы на изменение - документы, где описываются объекты разработки, которые необходимо изменить, и причины этих изменений.
(рис 13.1) Генерация отчета о покрытии и изменения по результатам его анализаНедостаточное покрытие может свидетельствовать о неполноте системы тестов или тест-требований, в этом случае в запросе об изменении указывается на необходимость расширения системы тестов или тест-требований. Другой причиной недостаточного покрытия могут быть участки защитного кода, которые никогда не выполнятся даже в случае нештатной работы системы. В этом случае в запросе на изменения указывается на необходимость модификации исходных текстов либо отмечается, что для этого участка программной системы не требуется покрытие. В качестве третьей причины недостаточного покрытия может выступать рассогласование требований и программного кода системы, в результате которого в коде могут остаться неиспользуемые более участки либо, наоборот, появиться участки, рассчитанные на будущее (и реализующие функциональность, не описанную в требованиях). В этом случае в запросе на изменение указывается на необходимость модификации требований и/или кода системы для приведения их в согласованное состояние.
Типичный отчет о покрытии представляет собой список структурных элементов покрываемого программного кода (функций или методов), содержащий для каждого структурного элемента следующую информацию:
Кроме того, отчет о покрытии содержит заголовочную информацию, позволяющую идентифицировать отчет, и общий итог - общую степень покрытия всех функций, для которых собирается информация о покрытии.
Пример такого отчета о покрытии приведен ниже.
Coverage Report Generated 10/07/2006 for file Testing_Facilities.cpp ---------------------------------------------------- 1) function main_Menu() Coverage: Instructions Elements: 25 structured lines of code (SLOCs) Covered: 22 lines (88%) Not covered: 291 default: 292 return -1; 293 break; Coverage: Branches Elements: 5 branches Covered: 4 branches (80%) Not covered (starting and ending lines only): default: break; ---------------------------------------------------- 2) function item_Help() Coverage: Instructions Elements: 180 structured lines of code (SLOCs) Covered: 180 lines (100%) Coverage: Branches Elements: 2 branches Covered: 2 branches (80%) ---------------------------------------------------- Total functions: 2 Total instructions coverage: 98.5% Total branches coverage: 86%
Отчет о покрытии может создаваться либо для всех функций программного модуля или всего проекта, либо выборочно для определенных функций.
В случае, если размер функций, для которых генерируется выборочный отчет, невелик, может применяться другая форма отчета о покрытии, в котором покрытый и непокрытый программный код выделяется различными цветами. Такая форма неприменима для покрытия ветвей и логических условий, но может применяться для покрытия по строкам.
Пример такого отчета приведен ниже:

Зеленым цветом отмечены выполненные в результате тестирования участки метода, красным - не выполненные.
Конкретная форма отчета о покрытии определяется инструментарием и технологическими процессами проекта.
Рассмотрим, например, отчет о структурном покрытии, генерируемый при помощи средства для анализа программного кода CodeTEST компании Metrowerks.
Сбор покрытия производится по определенному уровню покрытия, информация об этом входит в состав заголовка отчета о покрытии. В данном случае програмный код покрывался по MC/DC.
CodeTEST Advanced Coverage Tools
Modified Condition Decision Coverage Report (MCDC), DO-178B Level A
CodeTEST Report Generator 2.2.04
Report generated on Sun Aug 21 14:28:16 2005
IDB File:
<Path_to_IDB_file>
42963330-1C0 Thu May 26 21:36:00 2005
Далее выводится информация о проценте покрытия по всем модулям в совокупности (в данном случае, это 33 модуля):
Overall Summary (MCDC): 33 Files
1405 true-false decisions
674 48.0% covered
494 35.2% partially covered
237 16.9% not covered
1928 conditions in the decisions
1068 55.4% covered
571 29.6% partially covered
289 15.0% not covered
278 case branches
154 55.4% covered
124 44.6% not covered
581 coverage events
504 86.7% covered
77 13.3% not covered
Рассмотрим более подробно каждую из характеристик.
True-false decisions - количество логических выражений, в данном случае их 1405. Из этого числа на оба возможных значения ( True и False ) покрыто лишь 674, еще 494 покрыто на какое-то одно из значений, а 237 не покрыто вообще.
Conditions in the decisions - количество логических условий внутри логических выражений. Как можно догадаться, их количество не может быть меньше количества логических выражений. Непокрытие логических условий явным образом влечет за собой непокрытие логических выражений. Факт, что если все условия будут покрыты, то все выражения также будут покрыты.
Case branches - количество веток ветвления операторов выбора ( select ). Ветка считается покрытой, если выражение, стоящее в условии оператора select, принимает значение, соответствующее данному варианту выбора ( case ), в результате чего ветка выполняется.
Coverage events - в данном случае, это количество точек входа / выхода в функциях. Точка входа в функцию считается покрытой, если эта функция была вызвана хотя бы один раз. Точками выхода являются точка окончания функции ( } ), когда управление передается в место вызова этой функции, а также операторы возврата ( return ), после выполнения которых управление также передается в место вызова функции.
Затем выводится информация для первого модуля, а именно: имя модуля, путь к файлу на диске, дата последнего изменения, контрольная сумма. После этого выводится суммарная информация о покрытии только для этого модуля (для всех его функций, количество которых также указывается). Структура этой информации аналогична структуре, описанной выше:
1. File <Module_1_name.cpp> in <Path_to_module_1>
Last Modified: Fri Oct 15 18:34:14 2004
Checksum: CEDBAB67
File Summary (Extended MCDC): 6 Functions
24 true-false decisions
10 41.7% covered
11 45.8% partially covered
3 12.5% not covered
39 conditions in the decisions
20 51.3% covered
15 38.5% partially covered
4 10.3% not covered
0 case branches
12 coverage events
12 100.0% covered
0 0.0% not covered
После этого происходит поочередный вывод суммарной информации для каждой из функций в отдельности и также всех ключевых участков функции, влияющих на покрытие, а именно: точки входа / выхода, логические выражения, логические условия, операторы выбора. При этом для каждого из этих ключевых участков выводится информация о степени покрытия, где возможными значениями могут быть:
COVERED - участок полностью покрыт в понятиях типа, к которому он приписан;
PARTIALLY covered - участок частично покрыт. Применимо только к логическим выражениям и условиям и указывает на то, что выражение (условие) покрыто на какое-то одно из двух возможных значений;
NOT covered - участок не покрыт. Это означает, что данный участок не выполнялся в процессе работы скомпилированного программного кода.
Ниже представлен типичный результат покрытия для функции.
1.1 Function <Function_1>
void Function_1(void)
Function Summary (MCDC):
3 true-false decisions
0 0.0% covered
2 66.7% partially covered
1 33.3% not covered
5 conditions in the decisions
1 20.0% covered
3 60.0% partially covered
1 20.0% not covered
0 case branches
2 coverage events
2 100.0% covered
0 0.0% not covered
coverage line 266: function entry
COVERED
decision line 267: if statement
if ((A == B) (...
T F
1: *ttt *fxx ((A == ...) COVERED
2: *ttt tfx ((C...) PARTIALLY covered
3: *ttt ttf ((D == 0) PARTIALLY covered
decision line 271: if statement
if (E <= 0)
T F
1: t *f (E <= 0) PARTIALLY covered
decision line 276: if statement
if (D == 0)
T F
1: t f (D...) NOT covered
coverage line 291: function end
}
COVERED
Следует обратить внимание на то, каким образом происходит разбор логических выражений. Предположим, что у нас имеется выражение вида:
if ((A==B) (C > 0) (D == 0))
и пусть результат покрытия для него такой, как приведен выше ( decision line 267: if statement ). Для этого выражения строится таблица, где в каждой строке помещается информация для каждого из логических условий, входящих в это логическое выражение. Нумерация логических условий начинается с 1, в нашем случае их 3.
В первом столбце указывается комбинация значений логических условий (с участием рассматриваемого условия), которую необходимо выставить, чтобы логическое выражение приняло значение True. В данном случае, так как все условия соединены логическим оператором "И" ( ), такой комбинацией может быть только TTT. Если указанная комбинация была сформирована в процессе тестирования программы, то она помечается символом ( * ).
Во втором столбце указывается комбинация значений логических условий (с участием рассматриваемого условия), которую необходимо выставить, чтобы логическое выражение приняло значение False. В данном случае достаточно, чтобы хотя бы одно условие приняло значение False, при этом значения всех последующих условий не учитываются (это отображается символом X ).
Третий столбец - это вырезка текста логического условия, позволяющая легче ориентироваться в коде при анализе покрытия.
Из получившейся таблицы видно, что второе и третье логическое условие в процессе выполнения не принимали значения False. Определение причины этого и является задачей анализа структурного покрытия.
После того, как в рамках данного модуля будут рассмотрены все функции, рассматривается следующий модуль, и так далее. Мы видим, что структура отчетного файла, получаемого в результате работы CodeTEST, достаточно проста и имеет вложенную структуру.
Отчеты о покрытиях, создаваемые Microsoft Visual Studio Team Edition, будут рассмотрены на семинарских занятиях.
В некоторых случаях инструментальные средства сбора покрытия анализируют покрытие программного кода тестами не на уровне исходных текстов системы, а на уровне машинных инструкций. В этом случае степень покрытия зависит и от того, какой исполняемый код генерируется компилятором. Отчеты о покрытии в этом случае выглядят следующим образом (отчет о покрытии сгененирован при помощи отладчика Microtec XRAY для Motorola 680x0):
******* INSTRUCTION EXECUTION COVERAGE - Analyze Unit: Menu_Display
Function: DATA_PROCESSING\Menu_Display. Instruction(s) not executed:
5668 switch (Key)
0004A0F6 0352 BCHG D1,(A2)
0004A102 0466 0466 SUBI.W #$466,-(A6)
0004A106 0466 0466 SUBI.W #$466,-(A6)
0004A10A 0466 0466 SUBI.W #$466,-(A6)
0004A10E 0466 0466 SUBI.W #$466,-(A6)
0004A112 0466 0466 SUBI.W #$466,-(A6)
0004A116 0466 0474 SUBI.W #$474,-(A6)
5751 i = 1;
0004A4A6 7401 MOVEQ #$1,D2
Executed Total Percent Analyze-unit
467 475 98.32 DATA_PROCESSING\Menu_Display
0 unit(s) excluded.
******* BRANCH EXECUTION COVERAGE - Analyze Unit: Menu_Display
Function: DATA_PROCESSING\Menu_Display. Branch(es) not executed:
5612 if ( First_Call == TRUE ) { /* Only execute this block during th
00049E3A 6600 0722 BNE.W $4A55E Branch not taken.
5613 if ( MP_Rd_Config_Straps ( RAW_STRAPS, Strap_Config ) ==
00049E52 664A BNE.B $49E9E Branch not taken.
5750 if (i == 17)
0004A4A4 6602 BNE.B $4A4A8 Fall thru not taken.
Executed Total Percent Analyze-unit
74 77 96.10 DATA_PROCESSING\Menu_Display
0 unit(s) excluded.
Поскольку степень покрытия может меняться в зависимости от оптимизации при генерации кода, в некоторых случаях даже при полном выполнении всех операторов языка высокого уровня, на котором написана программная система, не удается достичь полного покрытия на уровне исполняемого кода.
Например, в случае покрытия следующей конструкции на языке C:
typedef enum
{
CC1 = 250,
CC2 = 251,
CC3 = 252
} E_CC;
…
E_CC key;
…
switch (key) {
case CC1: printf("CC1"); break;
case CC2: printf("CC2"); break;
case CC3: printf("CC3"); break;
}
компилятор Microtec C для Motorola 680x0 создаст таблицу возможных значений переменной key, в которой будут присутствовать все элементы от 0 до 255. Реально в программной системе возможно передать только значения констант CC1 - CC3, и в результате покрытыми окажутся только три ветки из 255 возможных в исполняемом коде. Никакими стандартными средствами увеличить степень такого покрытия нельзя. В этом случае отчет о покрытии сопровождается дополнительной информацией о причинах невозможности обеспечить полное покрытие.
Сбор информации о покрытии на уровне исполняемого кода наиболее часто применяется в высококритичных программных системах, где не допускается наличия "мертвого" исполняемого кода, который потенциально может привести к сбою или отказу во время работы системы. К таким системам в первую очередь можно отнести авиационные бортовые системы, медицинские системы и системы обеспечения безопасности информации.
Каждое несоответствие с требованиями, найденное тестировщиком, должно быть задокументировано в виде отчета о проблеме. Вероятность обнаружения и исправления ошибки, вызвавшей это несоответствие, зависит от того, насколько качественно она задокументирована. Отчеты о проблемах могут поступать не только от тестировщиков, но и от специалистов технической поддержки или пользователей, однако их общая цель - указать на наличие проблемы в системе, которая должна быть устранена. Если отчет составлен некорректно, разработчик не сможет устранить проблему, поэтому можно считать этот отчет одним из самых важных документов в цепочке тестовой документации.
Главное, что должно быть включено в отчет об ошибке, - это:
Любой отчет о проблеме должен быть составлен немедленно после ее обнаружения. Если отчет будет составлен спустя значительное время, повышается вероятность того, что в него не попадет какая-либо важная информация, которая поможет устранить причину проблемы в кратчайшие сроки.
Структура отчета о проблеме в целом мало различается в различных проектах, изменения обычно касаются только порядка и имен следования полей. Некоторые поля могут отражать специфику данного конкретного проекта, однако обычно эти поля следующие:
Обычный вид отчета о проблеме, соответствующего данной структуре, следующий:
Отчет о проблеме Порядковый номер отчета: Автор отчета: ___________________ Дата создания отчета: __ __ __ Документы/разделы, связанные с проблемой: …………………………………….. Идентификация объекта/процесса, где проявляется проблема: …………………………………………………………………………………………. Определение проблемы: …………………………………………………………………………………………. Автор решения: ___________________ Дата формирования решения __ __ __ Принятое решение: (возможно, ссылки на изменяемые компоненты/запросы на изменения) …………………………………………………………………………………………. Результаты анализа, определяющие, на содержание каких компонент влияет решение: …………………………………………………………………………………………. План проверок, восстанавливающих текущее состояние документов разработки …………………………………………………………………………………………. Оценка принятого автором отчета решения о проблеме: _ …………………………………………………………………………………………. ( 0 = полностью согласен 1 = не все аспекты проблемы учтены/разрешены 2 = основная часть проблемы осталась неразрешенной 3 = решение не адекватно проблеме - не устраняет ее)
На каждом этапе жизненного цикла разработки программной системы создается различного рода проектная документация. Как правило, документация каждого последующего этапа создается на базе документации предыдущего этапа. Для упрощения навигации по различным документам и в т.ч. упрощения верификации документации и самой системы часто используются перекрестные ссылки между разделами документов.
Так, например, часто применяемая практика заключается в том, что каждое требование в документах помечается уникальным идентификатором - якорем ( anchor ). Якоря в требованиях могут иметь, например, следующий формат:
[ANCHOR: код]
Здесь код записывается в виде AAA_RR_NNNNNN, где AAA - тип документа (SYS, ORD и т.п.), RR - номер раздела верхнего уровня, в котором содержится якорь, и NNNNNN - номер ссылки с ведущими нулями.
Требование в таком виде будет выглядеть следующим образом:
Для каждого вычислимого атрибута должна быть определена роль, от которой производится вычисления. [ANCHOR: SYS_02_000084].
Если возникает необходимость сослаться на требование из того же самого документа или из любого другого, то в ссылке указывается код якоря для соответствующего требования. Так, например, если ссылка записывается в тексте и имеет следующий формат:
[REF: код]
где код имеет тот же формат, что и для якоря, ссылка на требования будет иметь следующий вид:
Для доступа к названию роли в формуле расчета значения вычислимого атрибута должна использоваться мнемоника [RoleName]. [ANCHOR: SRD_02_000058] [REF: SYS_02_000084].
Система якорей и ссылок использует те же самые идеи, что и обычный гипертекст, однако, часто возникает необходимость не только в указании самого факта связи между требованиями или разделами документов, но и дополнительно указать тип связи. Например, можно выделить следующие типы связей:
В этом случае можно указывать тип ссылки рядом с кодом якоря, на который она ссылается. Однако, часто применяется и другой метод организации типизированных ссылок между документами - трассировочные таблицы.
В общем случае в строках и столбцах трассировочной таблицы указаны идентификаторы якорей, на которые и из которых идет ссылка, а в ячейке на пересечении строк и столбцов отмечается либо факт наличия ссылки, либо ее тип.
Трассировочные таблицы могут использоваться для машинного анализа ссылочной целостности проектной документации или для быстрой навигации в больших объемах документов.
Как уже было сказано в предыдущем разделе, одна из форм трассировочных таблиц подразумевает указание идентификаторов якорей в строках и столбцах и типа связи в ячейках на их пересечении. Такая таблица будет выглядеть следующим образом:
| SYS_01_0001 | SYS_01_0002 | SYS_01_0003 | SYS_01_0003 | |
| SRD_01_0001 | cross-ref |
variant |
||
| SRD_01_0002 | based on |
variant |
||
| SRD_01_0003 | based on |
variant |
||
| SRD_01_0004 | cross-ref |
variant |
В первом столбце перечислены якоря требований к программному обеспечению, в первой строке - якоря системных требований. На пересечении указаны типы ссылок: cross-ref - обычная информационная перекрестная ссылка; based on - требование к ПО, основанное на данном системном требовании; variant - может использоваться либо одно, либо другое требование к ПО в зависимости от варианта системы.
Также часто используется более простая форма трассировочных таблиц. В первом столбце перечисляются якоря или номера разделов документа, который ссылается на другие. В строке - названия документов, на которые идет ссылка, а в ячейках - якоря или номера разделов, на которые идет ссылка. Трассировочная таблица в этом случае будет выглядеть следующим образом:
| РД СВТ | Protection Profile | Protection Profile глава 6 | Protection Profile главы 1-4 | Комментарии |
|---|---|---|---|---|
| 2.2.2 КСЗ должен требовать от пользователей идентифицировать себя при запросах на доступ. | 5.2.2.4 FIA_UID.1.2 | 286, 288 | 82 O.USER_AUTHENTICATION, O.USER_IDENTIFICATION, 57 IdentificationAuthentication, 80 P.I_AND_A, 58 Non- |
|
| 2.2.2 КСЗ должен подвергать проверке подлинность идентификации - осуществлять аутентификацию. | 5.2.2.3 FAI_UAU.1.2 | 277, 280 | В названии трассировочного тега опечатка. Правильно - FIA_UAU.1.2 | |
| 2.2.2 КСЗ должен препятствовать доступу к защищаемым ресурсам неидентифицированных пользователей и пользователей, подлинность идентификации которых при аутентификации не подтвердилась. | 5.1.3.1 | 286, 287 | 5.1.3.1 - необходимые данные для аутентификации - атрибуты учетной записи пользователя |
Здесь РД СВТ - документ Гостехкомиссии РФ, включающий в себя требования по защищенности средств вычислительной техники [5], Protection Profile - один из аналогичных документов, используемых в США. Таблица представляет собой трассировку требований РД СВТ на требования различных глав Protection Profile. В первой строке указаны главы, а в ячейчах - конкретные разделы.
Степень покрытия программного кода тестами - важный количественный показатель, позволяющий оценить качество системы тестов, а в некоторых случаях - и качество тестируемой программной системы. Данные о степени покрытия помещаются в отчеты о покрытии, которые генерируются при выполнении тестов инструментальными средствами, поддерживающими процесс тестирования, т.е. по сути, генерируются средой тестирования (Рис 13.1). Формат отчетов о покрытии обычно единый внутри проекта или нескольких проектов и часто зависит от особенностей инструментальных средств тестирования.
В отчете о покрытии в стандартизированной форме указываются участки программного кода тестируемой системы (или ее части), которые не были выполнены во время выполнения тестовых примеров, т.е. не были покрыты тестами. Причины непокрытия анализируются тестировщиками, по результатам анализа составляются отчеты о проблемах и запросы на изменение - документы, где описываются объекты разработки, которые необходимо изменить, и причины этих изменений.
(рис 13.1) Генерация отчета о покрытии и изменения по результатам его анализаНедостаточное покрытие может свидетельствовать о неполноте системы тестов или тест-требований, в этом случае в запросе об изменении указывается на необходимость расширения системы тестов или тест-требований. Другой причиной недостаточного покрытия могут быть участки защитного кода, которые никогда не выполнятся даже в случае нештатной работы системы. В этом случае в запросе на изменения указывается на необходимость модификации исходных текстов либо отмечается, что для этого участка программной системы не требуется покрытие. В качестве третьей причины недостаточного покрытия может выступать рассогласование требований и программного кода системы, в результате которого в коде могут остаться неиспользуемые более участки либо, наоборот, появиться участки, рассчитанные на будущее (и реализующие функциональность, не описанную в требованиях). В этом случае в запросе на изменение указывается на необходимость модификации требований и/или кода системы для приведения их в согласованное состояние.
Типичный отчет о покрытии представляет собой список структурных элементов покрываемого программного кода (функций или методов), содержащий для каждого структурного элемента следующую информацию:
Кроме того, отчет о покрытии содержит заголовочную информацию, позволяющую идентифицировать отчет, и общий итог - общую степень покрытия всех функций, для которых собирается информация о покрытии.
Пример такого отчета о покрытии приведен ниже.
Coverage Report Generated 10/07/2006 for file Testing_Facilities.cpp ---------------------------------------------------- 1) function main_Menu() Coverage: Instructions Elements: 25 structured lines of code (SLOCs) Covered: 22 lines (88%) Not covered: 291 default: 292 return -1; 293 break; Coverage: Branches Elements: 5 branches Covered: 4 branches (80%) Not covered (starting and ending lines only): default: break; ---------------------------------------------------- 2) function item_Help() Coverage: Instructions Elements: 180 structured lines of code (SLOCs) Covered: 180 lines (100%) Coverage: Branches Elements: 2 branches Covered: 2 branches (80%) ---------------------------------------------------- Total functions: 2 Total instructions coverage: 98.5% Total branches coverage: 86%
Отчет о покрытии может создаваться либо для всех функций программного модуля или всего проекта, либо выборочно для определенных функций.
В случае, если размер функций, для которых генерируется выборочный отчет, невелик, может применяться другая форма отчета о покрытии, в котором покрытый и непокрытый программный код выделяется различными цветами. Такая форма неприменима для покрытия ветвей и логических условий, но может применяться для покрытия по строкам.
Пример такого отчета приведен ниже:

Зеленым цветом отмечены выполненные в результате тестирования участки метода, красным - не выполненные.
Конкретная форма отчета о покрытии определяется инструментарием и технологическими процессами проекта.
Рассмотрим, например, отчет о структурном покрытии, генерируемый при помощи средства для анализа программного кода CodeTEST компании Metrowerks.
Сбор покрытия производится по определенному уровню покрытия, информация об этом входит в состав заголовка отчета о покрытии. В данном случае програмный код покрывался по MC/DC.
CodeTEST Advanced Coverage Tools
Modified Condition Decision Coverage Report (MCDC), DO-178B Level A
CodeTEST Report Generator 2.2.04
Report generated on Sun Aug 21 14:28:16 2005
IDB File:
<Path_to_IDB_file>
42963330-1C0 Thu May 26 21:36:00 2005
Далее выводится информация о проценте покрытия по всем модулям в совокупности (в данном случае, это 33 модуля):
Overall Summary (MCDC): 33 Files
1405 true-false decisions
674 48.0% covered
494 35.2% partially covered
237 16.9% not covered
1928 conditions in the decisions
1068 55.4% covered
571 29.6% partially covered
289 15.0% not covered
278 case branches
154 55.4% covered
124 44.6% not covered
581 coverage events
504 86.7% covered
77 13.3% not covered
Рассмотрим более подробно каждую из характеристик.
True-false decisions - количество логических выражений, в данном случае их 1405. Из этого числа на оба возможных значения ( True и False ) покрыто лишь 674, еще 494 покрыто на какое-то одно из значений, а 237 не покрыто вообще.
Conditions in the decisions - количество логических условий внутри логических выражений. Как можно догадаться, их количество не может быть меньше количества логических выражений. Непокрытие логических условий явным образом влечет за собой непокрытие логических выражений. Факт, что если все условия будут покрыты, то все выражения также будут покрыты.
Case branches - количество веток ветвления операторов выбора ( select ). Ветка считается покрытой, если выражение, стоящее в условии оператора select, принимает значение, соответствующее данному варианту выбора ( case ), в результате чего ветка выполняется.
Coverage events - в данном случае, это количество точек входа / выхода в функциях. Точка входа в функцию считается покрытой, если эта функция была вызвана хотя бы один раз. Точками выхода являются точка окончания функции ( } ), когда управление передается в место вызова этой функции, а также операторы возврата ( return ), после выполнения которых управление также передается в место вызова функции.
Затем выводится информация для первого модуля, а именно: имя модуля, путь к файлу на диске, дата последнего изменения, контрольная сумма. После этого выводится суммарная информация о покрытии только для этого модуля (для всех его функций, количество которых также указывается). Структура этой информации аналогична структуре, описанной выше:
1. File <Module_1_name.cpp> in <Path_to_module_1>
Last Modified: Fri Oct 15 18:34:14 2004
Checksum: CEDBAB67
File Summary (Extended MCDC): 6 Functions
24 true-false decisions
10 41.7% covered
11 45.8% partially covered
3 12.5% not covered
39 conditions in the decisions
20 51.3% covered
15 38.5% partially covered
4 10.3% not covered
0 case branches
12 coverage events
12 100.0% covered
0 0.0% not covered
После этого происходит поочередный вывод суммарной информации для каждой из функций в отдельности и также всех ключевых участков функции, влияющих на покрытие, а именно: точки входа / выхода, логические выражения, логические условия, операторы выбора. При этом для каждого из этих ключевых участков выводится информация о степени покрытия, где возможными значениями могут быть:
COVERED - участок полностью покрыт в понятиях типа, к которому он приписан;
PARTIALLY covered - участок частично покрыт. Применимо только к логическим выражениям и условиям и указывает на то, что выражение (условие) покрыто на какое-то одно из двух возможных значений;
NOT covered - участок не покрыт. Это означает, что данный участок не выполнялся в процессе работы скомпилированного программного кода.
Ниже представлен типичный результат покрытия для функции.
1.1 Function <Function_1>
void Function_1(void)
Function Summary (MCDC):
3 true-false decisions
0 0.0% covered
2 66.7% partially covered
1 33.3% not covered
5 conditions in the decisions
1 20.0% covered
3 60.0% partially covered
1 20.0% not covered
0 case branches
2 coverage events
2 100.0% covered
0 0.0% not covered
coverage line 266: function entry
COVERED
decision line 267: if statement
if ((A == B) (...
T F
1: *ttt *fxx ((A == ...) COVERED
2: *ttt tfx ((C...) PARTIALLY covered
3: *ttt ttf ((D == 0) PARTIALLY covered
decision line 271: if statement
if (E <= 0)
T F
1: t *f (E <= 0) PARTIALLY covered
decision line 276: if statement
if (D == 0)
T F
1: t f (D...) NOT covered
coverage line 291: function end
}
COVERED
Следует обратить внимание на то, каким образом происходит разбор логических выражений. Предположим, что у нас имеется выражение вида:
if ((A==B) (C > 0) (D == 0))
и пусть результат покрытия для него такой, как приведен выше ( decision line 267: if statement ). Для этого выражения строится таблица, где в каждой строке помещается информация для каждого из логических условий, входящих в это логическое выражение. Нумерация логических условий начинается с 1, в нашем случае их 3.
В первом столбце указывается комбинация значений логических условий (с участием рассматриваемого условия), которую необходимо выставить, чтобы логическое выражение приняло значение True. В данном случае, так как все условия соединены логическим оператором "И" ( ), такой комбинацией может быть только TTT. Если указанная комбинация была сформирована в процессе тестирования программы, то она помечается символом ( * ).
Во втором столбце указывается комбинация значений логических условий (с участием рассматриваемого условия), которую необходимо выставить, чтобы логическое выражение приняло значение False. В данном случае достаточно, чтобы хотя бы одно условие приняло значение False, при этом значения всех последующих условий не учитываются (это отображается символом X ).
Третий столбец - это вырезка текста логического условия, позволяющая легче ориентироваться в коде при анализе покрытия.
Из получившейся таблицы видно, что второе и третье логическое условие в процессе выполнения не принимали значения False. Определение причины этого и является задачей анализа структурного покрытия.
После того, как в рамках данного модуля будут рассмотрены все функции, рассматривается следующий модуль, и так далее. Мы видим, что структура отчетного файла, получаемого в результате работы CodeTEST, достаточно проста и имеет вложенную структуру.
Отчеты о покрытиях, создаваемые Microsoft Visual Studio Team Edition, будут рассмотрены на семинарских занятиях.
В некоторых случаях инструментальные средства сбора покрытия анализируют покрытие программного кода тестами не на уровне исходных текстов системы, а на уровне машинных инструкций. В этом случае степень покрытия зависит и от того, какой исполняемый код генерируется компилятором. Отчеты о покрытии в этом случае выглядят следующим образом (отчет о покрытии сгененирован при помощи отладчика Microtec XRAY для Motorola 680x0):
******* INSTRUCTION EXECUTION COVERAGE - Analyze Unit: Menu_Display
Function: DATA_PROCESSING\Menu_Display. Instruction(s) not executed:
5668 switch (Key)
0004A0F6 0352 BCHG D1,(A2)
0004A102 0466 0466 SUBI.W #$466,-(A6)
0004A106 0466 0466 SUBI.W #$466,-(A6)
0004A10A 0466 0466 SUBI.W #$466,-(A6)
0004A10E 0466 0466 SUBI.W #$466,-(A6)
0004A112 0466 0466 SUBI.W #$466,-(A6)
0004A116 0466 0474 SUBI.W #$474,-(A6)
5751 i = 1;
0004A4A6 7401 MOVEQ #$1,D2
Executed Total Percent Analyze-unit
467 475 98.32 DATA_PROCESSING\Menu_Display
0 unit(s) excluded.
******* BRANCH EXECUTION COVERAGE - Analyze Unit: Menu_Display
Function: DATA_PROCESSING\Menu_Display. Branch(es) not executed:
5612 if ( First_Call == TRUE ) { /* Only execute this block during th
00049E3A 6600 0722 BNE.W $4A55E Branch not taken.
5613 if ( MP_Rd_Config_Straps ( RAW_STRAPS, Strap_Config ) ==
00049E52 664A BNE.B $49E9E Branch not taken.
5750 if (i == 17)
0004A4A4 6602 BNE.B $4A4A8 Fall thru not taken.
Executed Total Percent Analyze-unit
74 77 96.10 DATA_PROCESSING\Menu_Display
0 unit(s) excluded.
Поскольку степень покрытия может меняться в зависимости от оптимизации при генерации кода, в некоторых случаях даже при полном выполнении всех операторов языка высокого уровня, на котором написана программная система, не удается достичь полного покрытия на уровне исполняемого кода.
Например, в случае покрытия следующей конструкции на языке C:
typedef enum
{
CC1 = 250,
CC2 = 251,
CC3 = 252
} E_CC;
…
E_CC key;
…
switch (key) {
case CC1: printf("CC1"); break;
case CC2: printf("CC2"); break;
case CC3: printf("CC3"); break;
}
компилятор Microtec C для Motorola 680x0 создаст таблицу возможных значений переменной key, в которой будут присутствовать все элементы от 0 до 255. Реально в программной системе возможно передать только значения констант CC1 - CC3, и в результате покрытыми окажутся только три ветки из 255 возможных в исполняемом коде. Никакими стандартными средствами увеличить степень такого покрытия нельзя. В этом случае отчет о покрытии сопровождается дополнительной информацией о причинах невозможности обеспечить полное покрытие.
Сбор информации о покрытии на уровне исполняемого кода наиболее часто применяется в высококритичных программных системах, где не допускается наличия "мертвого" исполняемого кода, который потенциально может привести к сбою или отказу во время работы системы. К таким системам в первую очередь можно отнести авиационные бортовые системы, медицинские системы и системы обеспечения безопасности информации.
Каждое несоответствие с требованиями, найденное тестировщиком, должно быть задокументировано в виде отчета о проблеме. Вероятность обнаружения и исправления ошибки, вызвавшей это несоответствие, зависит от того, насколько качественно она задокументирована. Отчеты о проблемах могут поступать не только от тестировщиков, но и от специалистов технической поддержки или пользователей, однако их общая цель - указать на наличие проблемы в системе, которая должна быть устранена. Если отчет составлен некорректно, разработчик не сможет устранить проблему, поэтому можно считать этот отчет одним из самых важных документов в цепочке тестовой документации.
Главное, что должно быть включено в отчет об ошибке, - это:
Любой отчет о проблеме должен быть составлен немедленно после ее обнаружения. Если отчет будет составлен спустя значительное время, повышается вероятность того, что в него не попадет какая-либо важная информация, которая поможет устранить причину проблемы в кратчайшие сроки.
Структура отчета о проблеме в целом мало различается в различных проектах, изменения обычно касаются только порядка и имен следования полей. Некоторые поля могут отражать специфику данного конкретного проекта, однако обычно эти поля следующие:
Обычный вид отчета о проблеме, соответствующего данной структуре, следующий:
Отчет о проблеме Порядковый номер отчета: Автор отчета: ___________________ Дата создания отчета: __ __ __ Документы/разделы, связанные с проблемой: …………………………………….. Идентификация объекта/процесса, где проявляется проблема: …………………………………………………………………………………………. Определение проблемы: …………………………………………………………………………………………. Автор решения: ___________________ Дата формирования решения __ __ __ Принятое решение: (возможно, ссылки на изменяемые компоненты/запросы на изменения) …………………………………………………………………………………………. Результаты анализа, определяющие, на содержание каких компонент влияет решение: …………………………………………………………………………………………. План проверок, восстанавливающих текущее состояние документов разработки …………………………………………………………………………………………. Оценка принятого автором отчета решения о проблеме: _ …………………………………………………………………………………………. ( 0 = полностью согласен 1 = не все аспекты проблемы учтены/разрешены 2 = основная часть проблемы осталась неразрешенной 3 = решение не адекватно проблеме - не устраняет ее)
На каждом этапе жизненного цикла разработки программной системы создается различного рода проектная документация. Как правило, документация каждого последующего этапа создается на базе документации предыдущего этапа. Для упрощения навигации по различным документам и в т.ч. упрощения верификации документации и самой системы часто используются перекрестные ссылки между разделами документов.
Так, например, часто применяемая практика заключается в том, что каждое требование в документах помечается уникальным идентификатором - якорем ( anchor ). Якоря в требованиях могут иметь, например, следующий формат:
[ANCHOR: код]
Здесь код записывается в виде AAA_RR_NNNNNN, где AAA - тип документа (SYS, ORD и т.п.), RR - номер раздела верхнего уровня, в котором содержится якорь, и NNNNNN - номер ссылки с ведущими нулями.
Требование в таком виде будет выглядеть следующим образом:
Для каждого вычислимого атрибута должна быть определена роль, от которой производится вычисления. [ANCHOR: SYS_02_000084].
Если возникает необходимость сослаться на требование из того же самого документа или из любого другого, то в ссылке указывается код якоря для соответствующего требования. Так, например, если ссылка записывается в тексте и имеет следующий формат:
[REF: код]
где код имеет тот же формат, что и для якоря, ссылка на требования будет иметь следующий вид:
Для доступа к названию роли в формуле расчета значения вычислимого атрибута должна использоваться мнемоника [RoleName]. [ANCHOR: SRD_02_000058] [REF: SYS_02_000084].
Система якорей и ссылок использует те же самые идеи, что и обычный гипертекст, однако, часто возникает необходимость не только в указании самого факта связи между требованиями или разделами документов, но и дополнительно указать тип связи. Например, можно выделить следующие типы связей:
В этом случае можно указывать тип ссылки рядом с кодом якоря, на который она ссылается. Однако, часто применяется и другой метод организации типизированных ссылок между документами - трассировочные таблицы.
В общем случае в строках и столбцах трассировочной таблицы указаны идентификаторы якорей, на которые и из которых идет ссылка, а в ячейке на пересечении строк и столбцов отмечается либо факт наличия ссылки, либо ее тип.
Трассировочные таблицы могут использоваться для машинного анализа ссылочной целостности проектной документации или для быстрой навигации в больших объемах документов.
Как уже было сказано в предыдущем разделе, одна из форм трассировочных таблиц подразумевает указание идентификаторов якорей в строках и столбцах и типа связи в ячейках на их пересечении. Такая таблица будет выглядеть следующим образом:
| SYS_01_0001 | SYS_01_0002 | SYS_01_0003 | SYS_01_0003 | |
| SRD_01_0001 | cross-ref |
variant |
||
| SRD_01_0002 | based on |
variant |
||
| SRD_01_0003 | based on |
variant |
||
| SRD_01_0004 | cross-ref |
variant |
В первом столбце перечислены якоря требований к программному обеспечению, в первой строке - якоря системных требований. На пересечении указаны типы ссылок: cross-ref - обычная информационная перекрестная ссылка; based on - требование к ПО, основанное на данном системном требовании; variant - может использоваться либо одно, либо другое требование к ПО в зависимости от варианта системы.
Также часто используется более простая форма трассировочных таблиц. В первом столбце перечисляются якоря или номера разделов документа, который ссылается на другие. В строке - названия документов, на которые идет ссылка, а в ячейках - якоря или номера разделов, на которые идет ссылка. Трассировочная таблица в этом случае будет выглядеть следующим образом:
| РД СВТ | Protection Profile | Protection Profile глава 6 | Protection Profile главы 1-4 | Комментарии |
|---|---|---|---|---|
| 2.2.2 КСЗ должен требовать от пользователей идентифицировать себя при запросах на доступ. | 5.2.2.4 FIA_UID.1.2 | 286, 288 | 82 O.USER_AUTHENTICATION, O.USER_IDENTIFICATION, 57 IdentificationAuthentication, 80 P.I_AND_A, 58 Non- |
|
| 2.2.2 КСЗ должен подвергать проверке подлинность идентификации - осуществлять аутентификацию. | 5.2.2.3 FAI_UAU.1.2 | 277, 280 | В названии трассировочного тега опечатка. Правильно - FIA_UAU.1.2 | |
| 2.2.2 КСЗ должен препятствовать доступу к защищаемым ресурсам неидентифицированных пользователей и пользователей, подлинность идентификации которых при аутентификации не подтвердилась. | 5.1.3.1 | 286, 287 | 5.1.3.1 - необходимые данные для аутентификации - атрибуты учетной записи пользователя |
Здесь РД СВТ - документ Гостехкомиссии РФ, включающий в себя требования по защищенности средств вычислительной техники [5], Protection Profile - один из аналогичных документов, используемых в США. Таблица представляет собой трассировку требований РД СВТ на требования различных глав Protection Profile. В первой строке указаны главы, а в ячейчах - конкретные разделы.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.