C++Test操作手册.docx
《C++Test操作手册.docx》由会员分享,可在线阅读,更多相关《C++Test操作手册.docx(19页珍藏版)》请在冰点文库上搜索。
C++Test操作手册
A-SPICE
C++test操作手册
撰写部门:
手写算法组
发行范围:
全公司
变更记录
版本号
修改点说明
变更人
变更日期
审批人
审批日期
V1.0
正式发布
赵哲
2017-6-11
张文涛
2017-10-31
V1.1
修改,
1.加入附录-MISRA-C2012规则
2.修改格式
张文涛
2017-10-30
王杰
2017-10-31
修改点说明的内容有如下几种:
创建、修改(+修改说明)、删除(+删除说明)
C++test介绍
ParasoftC++test是一个集成解决方案,用于使一系列被广泛证明可改进软件开发团队生产力和软件质量的最佳实践得以自动化处理。
通过C++test,可进行编码策略增强、静态分析、综合代码复审、单元测试和组件测试、以及运行时错误检测,以此向团队提供一种确保C和C++代码达到其预期功能的实用方法。
C++test安装
第一步:
打开安装源程序,同普通的windows应用程序一样,选择安装路径,完成安装。
第二步:
在安装目录搜索libs_sp.jar并删除;在安装目录找lic_client.jar并替换
第三步:
运行程序,打开许可证页面,
许可证:
网络
版本:
定制版定制:
全选
确定,至此完成安装过程
静态分析
在静态分析栏中的Results标签是对静态分析结果的一个罗列。
每个红色精灵帽都代表一种违规行为,而它旁边的数字则代表测试代码中出现这种违规的次数。
紧接着的字母表明违规行为的严重级别。
再后面就是对这条规范的大致描述以及规则编号。
测试配置中的“静态”标签则是对这些规则的管理,当用户需要使用某条规则的时候,只需要在相应规则左侧的方框内打上勾就表明选择了该条规则。
而当用户不需要某条规则检查的时候,只需要去掉相应规则的勾就可以了。
1.1规则设定
●开发人员在做静态测试时启用的规则为MISRAC2012[MISRA2012],规则详情参见附录MISRA-C2012中内容。
MISRA-C2012检查项分为两大类,一类称为[指导(Directives)],另一类称为[规则(Rules)]。
汉王项目要求选择全部规范进行静态分析检查。
1.2静态测试实施
开发人员选择好被测源文件后依次选择测试执行->内建->StaticAnalysis->MISRA-C2012,即可开始运行测试程序。
如需自定义启用禁用规则,可在测试配置中复制内建测试配置,然后再用户自定义中修改即可(内建项均为默认配置,不可修改,如需修改必须建自定义项),最后依次选择测试执行->用户自定义->“MISRA-C2012自定义名称”。
1.3查看结果
测试完成后,点击“proceed”来生成测试报告文档,结果保存在htlm中,可点击“configure...”设置生成路径,并可在首选项中按自己需求设置报表内容和保存格式等。
开发人员根据静态分析报告显示的问题修改代码,修改后再次利用静态分析工具进行分析,得出分析结果。
对于静态分析检查出来的问题,如果不予修改,给予放行,要经过项目经理批准,最终对放行的问题给出放行说明,开发人员负责编写项目静态分析结果说明《MISRA-C2012检查结果说明》,即对放行的问题进行说明。
不能放行的规范条目如下
序号
指导:
MISRAC2012Directives[MISRA2012-DIR]
1
嵌入汇编程序时嵌入的过程应该是纯汇编程序[MISRA2012-DIR-4_3-3]
序号
规则:
MISRAC2012Rules[MISRA2012-RULE]
2
字面量零(0)不得用作空指针常量(null-pointer-constant)[MISRA2012-RULE-11_9_a-3]
3
用NULL来代替字面零(0)作为空指针常量[MISRA2012-RULE-11_9_b-3]
4
不应该使用逗号运算符[MISRA2012-RULE-12_3-4]
5
初始化器列表不应该包含持久的副作用[MISRA2012-RULE-13_1_a-3]
6
逻辑&&或者||运算符的右边操作数不应该包含副作用[MISRA2012-RULE-13_5-3]
7
sizeof操作符的参数不应该是含副作用的表达式[MISRA2012-RULE-13_6_a-2]
8
不应该在sizeof操作符的操作数中访问由一个不稳定的数值指定的对象[MISRA2012-RULE-13_6_b-2]
9
函数调用不得是sizeof运算符的操作数[MISRA2012-RULE-13_6_c-2]
10
不应该使用goto语句[MISRA2012-RULE-15_1-4]
11
goto语句应该跳转到随后在同一个函数中声明的标签[MISRA2012-RULE-15_2-3]
12
任何由goto语句引用的标签应该声明在同一个模块中,或者在一个包围goto语句的模块中[MISRA2012-RULE-15_3-3]
13
对于任何循环语句,不要有超过一个break或goto语句用于循环终止[MISRA2012-RULE-15_4-4]
14
'switch','while','do...while'或'for'语句的主体应该是复合语句[MISRA2012-RULE-15_6_a-3]
15
在'if'和'else'之后应该紧跟着复合语句[MISRA2012-RULE-15_6_b-3]
16
所有的'if...else-if'结构中应该由'else'分支结束[MISRA2012-RULE-15_7-3]
17
只能当最接近的封闭复合语句是switch语句主体部分时才能使用switch标签[MISRA2012-RULE-16_2-3]
18
无条件的break语句应该作为每一个非空case子句的结尾[MISRA2012-RULE-16_3_a-3]
19
无条件限制的break语句应作为所有非空default条件的终结。
[MISRA2012-RULE-16_3_b-3]
20
需要为switch语句提供default分支[MISRA2012-RULE-16_4_a-3]
21
'default'标签在结束'break'之前应该有一个语句或者一个注释[MISRA2012-RULE-16_4_b-3]
22
如果存在一个'default'标签,应该作为switch语句的第一个或最后一个switch标签[MISRA2012-RULE-16_5-3]
23
每一个switch语句应该含有至少两个switch子句[MISRA2012-RULE-16_6-3]
24
switch的表达式中不能出现有效的布尔类型值[MISRA2012-RULE-16_7_a-3]
25
switch表达式不应该表示一个有效的布尔值[MISRA2012-RULE-16_7_b-3]
26
函数原型应该总是对函数调用可见[MISRA2012-RULE-17_3-2]
27
非void返回类型的函数的所有退出路径应该有一个明确的包含表达式的返回语句[MISRA2012-RULE-17_4-2]
28
函数参数对应的数组类型参数应该包含合适数量的元素[MISRA2012-RULE-17_5-4]
29
应该使用具有非void返回类型的函数返回值[MISRA2012-RULE-17_7_a-3]
30
不得使用一个非void返回类型函数返回的值[MISRA2012-RULE-17_7_b-3]
31
不应该修改函数参数[MISRA2012-RULE-17_8-4]
32
对象的申明需要包含不超过2成指针嵌套[MISRA2012-RULE-18_5-4]
33
不得声明灵活的数组成员[MISRA2012-RULE-18_7-3]
34
不得使用可变长数组类型[MISRA2012-RULE-18_8-3]
35
禁止使用预处理操作符#和##[MISRA2012-RULE-20_10-4]
36
一个紧跟在#操作符的宏参数不应该在其后紧跟或在其前加上##操作符[MISRA2012-RULE-20_11-3]
37
一个被用作#或者##操作符的操作数的宏参数,并且它本身受制于进一步的宏替换,那么它应该只能被用作这些操作符的操作数[MISRA2012-RULE-20_12-3]
38
预处理指令即使被预处理器排除也必须有语法意义[MISRA2012-RULE-20_13-3]
39
在同一个文件中#else,#elif和#endif必须对应有#if或#ifdef预处理指令[MISRA2012-RULE-20_14-3]
40
字符',",/*或//不得出现在头文件的名称中[MISRA2012-RULE-20_2_a-3]
41
字符\不得出现在头文件的名称中[MISRA2012-RULE-20_2_b-3]
42
#include指令后面应当添加或是"filename"[MISRA2012-RULE-20_3-3]
43
C90中规定宏不应该与关键字定义为相同名称[MISRA2012-RULE-20_4_a-3]
44
C99中规定宏不应该与关键字定义为相同名称[MISRA2012-RULE-20_4_b-3]
45
禁止使用#undef[MISRA2012-RULE-20_5-4]
46
类似函数的宏的参数不应该包含类似预处理命令的标识[MISRA2012-RULE-20_6-3]
47
不得使用标准头文件[MISRA2012-RULE-21_11-3]
48
不得使用中的异常处理功能[MISRA2012-RULE-21_12-4]
49
禁止使用动态内存分配[MISRA2012-RULE-21_3-3]
50
禁止使用setjmp宏和longjmp函数[MISRA2012-RULE-21_4_a-3]
51
不要使用标准头文件[MISRA2012-RULE-21_4_b-3]
52
禁止使用标准库文件中的处理函数[MISRA2012-RULE-21_5_a-3]
53
禁止使用信号处理文件中的处理函数[MISRA2012-RULE-21_5_b-3]
54
不得使用标准的库的input/output函数[MISRA2012-RULE-21_6-3]
55
禁止使用stdlib.h中库函数atof,atoi和atol[MISRA2012-RULE-21_7-3]
56
禁止使用stdlib.h中的库函数abort,exit,getenv和system[MISRA2012-RULE-21_8-3]
57
函数不应该包含未使用的标签声明[MISRA2012-RULE-2_6-4]
58
禁止在C语言风格的注释中使用/*字符序列[MISRA2012-RULE-3_1_a-3]
59
字符序列//不得被用于C语言风格的注释中[MISRA2012-RULE-3_1_b-3]
60
字符序列/*不得被用于C++语言风格的注释中[MISRA2012-RULE-3_1_c-3]
61
不得在//注释中使用行合并[MISRA2012-RULE-3_2-3]
62
八进制和十六进制转义序列将被终止[MISRA2012-RULE-4_1-3]
63
禁止使用三字母词[MISRA2012-RULE-4_2-4]
64
由signed整型命名的位域应该有超过一位的长度[MISRA2012-RULE-6_2-3]
65
八进制常量(除了0)不应该被使用[MISRA2012-RULE-7_1-3]
66
使用大写'L'而非小写'l'来指定long类型[MISRA2012-RULE-7_3-3]
67
不能修改窄字符串字面量[MISRA2012-RULE-7_4-3]
68
内联函数应该声明为静态存储类[MISRA2012-RULE-8_10-3]
69
在一个列举列表内,含蓄指定列举常数的值应该是唯一的[MISRA2012-RULE-8_12-3]
70
不得使用严格的类型限定符[MISRA2012-RULE-8_14-3]
71
带有内部链接的对象和函数应使用静态关键字进行定义和声明[MISRA2012-RULE-8_8-3]
可以放行的规范条目如下
序号
MISRAC2012Directives[MISRA2012-DIR]
1
使用多重包含保护机制[MISRA2012-DIR-4_10-3]
2
禁止使用动态内存分配[MISRA2012-DIR-4_12-3]
3
所有汇编程序的使用应该被注释说明[MISRA2012-DIR-4_2-4]
4
代码段落不应该被“注释掉”[MISRA2012-DIR-4_4-4]
5
函数应该优先于类似函数宏的使用[MISRA2012-DIR-4_9-4]
序号
MISRAC2012Rules[MISRA2012-RULE]
6
禁止强制类型转换操作删除以指针指定的const或volatile限制[MISRA2012-RULE-11_8-3]
7
包含自增(++)或自减(--)运算符的表达式不应该有其它潜在的副作用[MISRA2012-RULE-13_3-4]
8
不得使用一个内置赋值运算符的结果[MISRA2012-RULE-13_4-4]
9
函数应该在其最后有单一的出口[MISRA2012-RULE-15_5-4]
10
不得使用va_list,va_arg,va_start,va_end,va_copy标识符[MISRA2012-RULE-17_1_a-3]
11
不得使用va_list,va_arg,va_start,va_end标识符[MISRA2012-RULE-17_1_b-3]
12
函数不应该直接或者间接地调用自己[MISRA2012-RULE-17_2-3]
13
不得使用联合体关键字[MISRA2012-RULE-19_2-4]
14
#include之前只允许有预处理命令和注释[MISRA2012-RULE-20_1-4]
15
在函数式宏定义中,每个参数的实例应该被括号括起来,除非它被用于#或##操作符[MISRA2012-RULE-20_7-3]
16
除在#ifdef预处理命令、#ifndef预处理命令和defined()操作符之外,所有的宏变量在使用前必须定义[MISRA2012-RULE-20_9_a-3]
17
不要使用在编译单元中未定义的预编译器指令#if和#elif宏[MISRA2012-RULE-20_9_b-3]
18
避免使用标准C库中与时间有关的函数[MISRA2012-RULE-21_10-3]
19
不得使用在中的bsearch和qsort库函数[MISRA2012-RULE-21_9-3]
20
在函数中不应该有未使用的参数[MISRA2012-RULE-2_7-4]
单元测试
1.4生成测试套件
我们在做单元测试前的准备工作必不可少,测试套件是根据源代码来生成的多个测试组,每组内都是具有相关性的测试用例。
选择待测源码后依次选择测试执行->内建->UnitTesting->GenerateTestSuites,当然也可在测试配置中自定义一个生成配置。
(我们可以在显示视图中打开测试用例浏览器,来查看生成后的测试套件以及测试用例)
1.5生成单元测试用例
测试用例是对单元测试的具体实施最小模块,每一条都是独立的子程序,用来独立测试被测单元。
我们先通过C++test工具来生成单元测试用例,以方便随后实施单元测试时修改其中具体内容。
生成单元测试用例步骤如下:
测试执行->内建->UnitTesting->GenerateUnitTests。
同测试套件一样可以自定义生成规则。
这里我们可以省略生成测试套件这一步,因为在GenerateUnitTests时,已经包含了生成测试套件的内容。
注意:
我们在复用测试脚本代码时,仅需要生成测试套件,将之前测试脚本拷贝进来即可。
1.6桩函数
桩函数提供被调函数的替代实现,使得可以独立地进行单元测试而不依赖外部文件或函数。
在使用桩函数时,C++test会重定向执行流程,调用一个桩函数替代原有函数。
桩函数主要有两个用途:
•将正在测试的代码从集成环境中隔离出来。
•在不可能影响函数行为、且需要使用替代实施的情况下进行测试。
您可以为任何测试用例定义自己的桩函数,不管是自动生成的测试用例还是用户定义的测试用例。
当您使用用户定义的桩函数时,你可以完全控制外部函数的返回值-无需具有真正可用的外部函数。
如果有了用户定义的桩函数,则即使原始函数可用,在测试执行期间也可以一直使用该桩函数。
如果原始定义最初不可用、但后来被添加了,C++test也会继续使用用户定义的桩函数。
如果您想要让它使用原始定义,则需要删除桩函数(或者将它标注出来)。
用户定义的桩函数采用的实施方式是,在函数定义中,函数名称前面加上"CppTest_Stub_"前缀。
例如:
/*C++testuserstubdefinitionforintdoSomething(inti)*/
EXTERN_C_LINKAGEintdoSomething(inti);
EXTERN_C_LINKAGEintCppTest_Stub_doSomething(inti)
{
returni+10;
}
桩函数的声明必须在桩函数文件中可访问到。
在大多数情况下,通过将相应的头文件包含到桩函数文件中来连接它。
1.7测试实施
到这里我们的准备工作已基本完成,可以开始编写自己的单元测试脚本了,根据需要和源码罗辑改写生成的测试用例脚本,以便符合项目单元测试需求。
C++test可以对任意一条或多条测试用例执行步骤如下:
首先找到测试用例浏览器,选取待测用例点击测试执行->内建->UnitTesting->RunUnitTests或测试执行->测试历史->RunUnitTests。
1.8根据结果完善测试脚本
开发人员每次测试执行完成后,会在源代码上用颜色区分开已覆盖的代码行和未被覆盖到的代码行,可以此完善测试脚本(默认绿色是已覆盖,红色是未覆盖)。
1.9查看结果
在测试用例浏览器中查看详细信息。
这包括:
•测试的通过/失败状态将用不同的颜色加以显示
•测试执行统计信息
1.10生成测试报告
同静态测试生成报告相同,测试完成后点击“proceed”生成本次此时执行后的测试结果报告。
附录MISRA-C2012规则
MISRA-CCodingStandard,C语言编码标准,把所有的规范分为两大类,一类称为[指导(Directives)],另一类称为[规则(Rules)]。
共计91条。
具体参见MISRA-C2012\index.html详细规则说明。
∙MISRAC2012Directives[MISRA2012-DIR]
o使用多重包含保护机制[MISRA2012-DIR-4_10-3]
o禁止使用动态内存分配[MISRA2012-DIR-4_12-3]
o所有汇编程序的使用应该被注释说明[MISRA2012-DIR-4_2-4]
o嵌入汇编程序时嵌入的过程应该是纯汇编程序[MISRA2012-DIR-4_3-3]
o代码段落不应该被“注释掉”[MISRA2012-DIR-4_4-4]
o函数应该优先于类似函数宏的使用[MISRA2012-DIR-4_9-4]
∙MISRAC2012Rules[MISRA2012-RULE]
o禁止强制类型转换操作删除以指针指定的const或volatile限制[MISRA2012-RULE-11_8-3]
o字面量零(0)不得用作空指针常量(null-pointer-constant)[MISRA2012-RULE-11_9_a-3]
o用NULL来代替字面零(0)作为空指针常量[MISRA2012-RULE-11_9_b-3]
o不应该使用逗号运算符[MISRA2012-RULE-12_3-4]
o初始化器列表不应该包含持久的副作用[MISRA2012-RULE-13_1_a-3]
o包含自增(++)或自减(--)运算符的表达式不应该有其它潜在的副作用[MISRA2012-RULE-13_3-4]
o不得使用一个内置赋值运算符的结果[MISRA2012-RULE-13_4-4]
o逻辑&&或者||运算符的右边操作数不应该包含副作用[MISRA2012-RULE-13_5-3]
osizeof操作符的参数不应该是含副作用的表达式[MISRA2012-RULE-13_6_a-2]
o不应该在sizeof操作符的操作数中访问由一个不稳定的数值指定的对象[MISRA2012-RULE-13_6_b-2]
o函数调用不得是sizeof运算符的操作数[MISRA2012-RULE-13_6_c-2]
o不应该使用goto语句[MISRA2012-RULE-15_1-4]
ogoto语句应该跳转到随后在同一个函数中声明的标签[MISRA2012-RULE-15_2-3]
o任何由goto语句引用的标签应该声明在同一个模块中,或者在一个包围goto语句的模块中[MISRA2012-RULE-15_3-3]
o对于任何循环语句,不要有超过一个break或goto语句用于循环终止[MISRA2012-RULE-15_4-4]
o函数应该在其最后有单一的出口[MISRA2012-RULE-15_5-4]
o'switch','while','do...while'或'for'语句的主体应该是复合语句[MISRA2012-RULE-15_6_a-3]
o在'if'和'else'之后应该紧跟着复合语句[MISRA2012-RULE-15_6_b-3]
o所有的'if...else-if'结构中应该由'else'分支结束[MISRA2012-RULE-15_7-3]
o只能当最接近的封闭复合语句是switch