基于故障模型的软件测试

  • 格式:pdf
  • 大小:154.28 KB
  • 文档页数:16

下载文档原格式

  / 16
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

void setp(char *s) { if(p!=NULL) delete []p; p=new char[strlen(s)+1]; strcpy(p,s); } ~base() { if(p) { delete[] p; p=NULL; }}
}; class derive: public base { public: derive() {} derive(derive &a) printf("derive copy constructor is calling\n"); }; int main(int argc, char* argv[]) { derive c; c.setp("this is c"); derive b(c); printf("c : %s\n",c.p); printf("b : %s\n",b.p); return 0; } 由于在主程序中有语句 b=c,如果缺少拷贝构造函数 base(base& a),则当程序执行析构函数时,对指针*p 就执行了两次释放操作,可能会造成死机。 (8) 如果在构造函数中有申请内存的操作, 且在其它程序中有两个对象直接或间接的赋值操作, 如果没有对“=”运算符进行重载定义, 则会产生两次释放同一个内存操作错误。 该类错误称为第 VIII 类 Memory leak 故障。
【例 6-2】 下列程序结构: …;str=malloc(10);…;delete(str);… 即是第 II 类 Memory leak 故障。 (3) pointer 是用 new 分配的变量,若存在 Pi 且在 Pi 上只存在一个 delete (pointer),则是正确的。反之,如果存在两个或两个以上 delete (str),或者无 delete (pointer),或者存 在一个或一个以上的 free (pointer),则是 III 类 Memory leak 故障。 【例 6-3】 下列程序结构: …;str=new(10);…;free(str);… 即是第 III 类 Memory leak 故障。 (4)pointer 是用 new[ ]分配的变量,若存在 Pi 且在 Pi 上只存在一个 delete[],则是正确的。反之,如果用 delete 或用 free 释放的则是 IV 类 Memory leak 故障。 【例 6-4】 下列程序结构: …;class A { }; t=new A[10]; …;delete t;… 即是第 IV 类 Memory leak 故障。 (5)多余的 delete 和 free 是 V 类 Memory leak 故障。 【例 6-5】 下列程序结构: …;char *str=”abc”,…free(str);… 即是第 V 类 Memory leak 故障。 (6)当申请内存的 pointer 发生变化后,用 delete 和 free 释放变化后的 pointer 是 VI 类 Memory leak 故障。 【例 6-6】 下列程序结构: …;char *p=malloc(10);…;++p;…;free(p); 即是第 VI 类 Memory leak 故障。 (7) 如果在构造函数中有申请内存的操作、且在其它函数中出现对象的拷贝,如果无拷贝构造函数,则会产生析构函数对内存会出现重复释放的错误。该类错误称为第 VII 类 Memory leak 故障。 【例 6-7】 下列程序: class base { public: char *p; public: base() { p=new char[strlen("default value")+1]; strcpy(p,"default value"); printf("base constructor is calling\n"); }
} 由于在主程序中有语句 b=a 的操作,如果没有对“=”运算符的重载定义,则当程序执行析构函数时,对指针*p 就执行了两次释放操作,可能会造成死机。 (9)在“=”重载操作中,如果涉及到指针操作,则必须判断两个对象是否为同一个对象,否则当进行释放指针的操作时,就可能产生错误。该类错误称为第 IX 类 Memory leak 故障。 【例 6-9】 下列程序: class MyString { public: char *mChars; MyString() { mChars=new char[strlen("default value")+1]; strcpy(mChars,"default value"); } MyString& operator= (const MyString& rhs); }; MyString& MyString::operator= (const MyString& rhs) { if (rhs.mChars != NULL) { delete[] mChars; mChars = new char [strlen (rhs.mChars)+1]; strcpy (mChars, rhs.mChars); } else { mChars = NULL; } return *this; } int main(int argc, char* argv[]) { MyString a; printf("a.mChars is %s\n",a.mChars); a=a; printf("a.mChars is %s\n",a.mChars); return 0; } 如果在上面的程序中,缺少 if(&rhs==this) return *this,则会产生指针将被释放两次,造成错误。 MLF 故障是在 C++中是非常危险的, 若在某个函数中有 MLF 故障, 则当多次运行该函数时, 由于申请的内存没有释放, 可能会造成内存空间不足而造成系统死机或异常退出。 2.数组越界故障的故障模型( OOBF) 定义 6.2:数组越界故障:设某数组定义为 Array[min~max],若引用 Array[i]且 i<min 或 i>max 都是数组越界故障。在 C++中,若 i<0 或 i 砿 ax 是数组越界故障。 (1)对程序中任何出现 Array[i]的地方,都要判断 i 的范围,可能有三种情况: · 若 i 是在数组定义的范围内,则是正确的; · 若 i 是在数组定义的范围外,则是 OBAF;
基于故障模型的软件测试( 1 )
一种测试理论是否成熟的重要标志是测试对象是否有比较好的故障模型,故障模型必须满足下列几个条件: (1)该模型下的故障是符合实际的。也就是说,该模型下所定义的故障在实际工程中是大量存在的。 (2)基于该模型的故障数目是可以容忍的,一般来讲,故障个数跟系统的规模成线性关系。 (3)该模型下的故障是可以测试的。存在一个算法,该算法是可以检测这些故障的。 由于软件的复杂性和软件缺陷的复杂性,自软件测试技术诞生以来,虽然有很多科学家在软件的故障模型方面做了大量的工作,但收效甚微。这在很大程度上影响了软件测试 技术的发展与进步。进入二十一世纪以来,随着社会对软件测试技术的需求越来越大,软件的质量越来越受到重视,软件的测试理论也得到快速发展。其中之一就是软件测试 故障模型的研究取得了重要进展。目前市场上已有多个基于故障模型的软件测试系统。基于故障的测试的好处在于: (1)针对性强:如果说某种模型的故障是经常发生的,并且在被测软件中是存在的,则面向故障的测试可以检测出此类故障。而不会像白盒测试和黑盒测试那样的不确定性。 (2)有些故障一次性测试是检测不出来的,这种故障用白盒测试和黑盒测试这两种方法是检测不出来的。例如,存储器泄露故障、空指针引用故障等。 (3)可以避免对其它测试方法对“小概率”检测效率比较低的情况。 6.1 基于错误检测的故障模型 故障模型是和语言本身相关的,不同的语言有着不同的故障模型。本节以 C++和 JAVA 语言为背景来描述其故障模型。这些故障模型是从大量工程实践中总结出来的,有 很强的工程背景。 1.存储泄漏的故障模型(MLF) 定义 6.1:内存泄漏故障(Memory Leak Faults):设在程序的某处申请了大小为 M 的空间,凡在程序结束时 M 或者 M 的一部分没被释放、或者多次释放 M 或 M 的一部分都 是内存泄漏故障。 MLF 有三种形式: · 遗漏故障:是指申请的内存没有被释放。 · 不匹配故障:是指申请函数和释放函数不匹配。 · 不相等的释放错误:是指释放的空间和申请的空间大小不一样。 在 C++中,MLF 的表现形式为: (1)在完整路径 Pi 申请内存,但在 Pi 上无任何内存释放函数,则是第 I 类 Memory leak 故障。 【例 6-1】 下列程序: 1 2 3 4 5 6 7 8 9 10 11 12 13 } 在程序的第 2 行,给变量 new_entry 分配了内存,当程序在第 8 行返回时并没有释放该内存,即是第 I 类 MLF 故障。 (2) pointer 是用 malloc 分配的变量,若存在 Pi 且在 Pi 上只存在一个 free (pointer),则是正确的。反之,如果存在两个或两个以上 free (pointer),或者无 free (pointer),或者 存在一个或一个以上的 delete (pointer),则都是 II 类 Memory leak 故障。 } new_entry->next = entry->next; entry->next = new_entry; return new_entry; listrec *add_list_entry (listrec *entry, int value) { listrec *new_entry = (listrec*) malloc (sizeof (listrec) ); if (!new_entry) { return NULL; } new_entry->value = value; if (!entry) { return NULL;
【例 6-10】 对下列程序结构: #define N 10 …… int data[N]; for (i = 0; i<=N; ++i) { int x = new_data(i); data[i] = foo(x); } 程序中的 data[i]就会产生越界错误。 【例 6-11】 对下列程序结构: int search_slots(int port) { int i = 0; while (++i<port) { if (slot_table[i]>port) return slot_tabe[i]; } return 0; } 除非能够确定 port 小于 slot_table[ ]的范围,否则这是一个故障。 · 若 i 是不确定的,则 Array[i]是否是 OBAF 也是不确定的; (2)字符串拷贝过程中存在的数组越界故障:字符串拷贝的一般形式为: copy(dest,source) 如果 source 的空间大小大于 dest 的空间大小,则是数组越界故障。否则,则是正确的。在 C++中,字符串拷贝的函数可能引起的故障有: 表 6.1 可能产生数组越界的函数
基于故障模型的软件测试( 2 )
【例 6-8】 下列程序: class base { public: char *p; base() { p=new char[strlen("default value")+1]; strcpy(p,"default value"); }
源自文库
void setp(char *s) { p=new char[strlen(s)+1]; strcpy(p,s); } ~base() { if(p) { delete[] p; p=NULL;}} }; int main(int argc, char* argv[]) { base a,b; b=a; return 0;