51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3953|回复: 1
打印 上一主题 下一主题

[原创] 实用单元测试技术(试贴) - 代码错误分类与基本测试方法

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2006-10-29 15:30:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
说明 试贴《实用单元测试技术》第一稿的一小部分。《实用单元测试技术》由鄙人原创,力求实用,内容主要来自实践,有些内容可能与教科书或主流看法不同,欢迎讨论,不对的地方欢迎拍砖。

代码错误分类与基本测试方法

从测试的角度来看,代码的错误可分为有特征错误和无特征错误,有特征错误又分为语法特征错误和行为特征错误。

语法特征错误并不是语法错误,语法错误会通不过编译,语法特征错误是指能通过编译,但是使用工具对代码进行分析,根据代码中的某些特征可以判断代码含有或可能含有错误,例如if(N=0),其特征是条件式中出现了赋值操作符,静态分析工具据此可以给出警告,现代编译器通常也会给出警告。

行为特征错误是指具有可捕捉的行为特征的错误,这类错误通常会导致程序崩溃或产生异常,或产生其他可识别的错误结果(如内存未释放)。例如给代码中给一个指针赋值,如果指针为空,程序就会崩溃,这就是行为特征错误,内存泄漏也属于行为特征错误。

除了有特征错误外,其他就是无特征错误了。例如一个加法函数 int Add(int a, int b){return a-b;};,错误是将加号写成了减号,这种错误不具有任何语法或行为特征。

有特征错误具有如下特点:
容易自我暴露:现代的编译器通常会对具有语法特征错误的代码发出警告,行为特征错误通常会导致程序崩溃,现代的IDE也通常能捕捉未释放内存,从而将错误暴露出来。
易于定位和调试:语法特征错误一般是很容易定位和修正的,行为特征错误也比较容易定位,根据程序的崩溃地址一般就能定位到源代码,错误源与产生错误的位置相隔一般也不太远。
总之,有特征错误对于用户来说,当然是不可接受的,但对于开发商来说,发现并消除有特征错误的成本相对较低,最麻烦的是无特征错误。

有特征错误和无特征错误各占多少比例呢?很难有一个准确的数据,不同的团队,不同的开发人员,比例会有所不同,以笔者个人经验和小范围的调查结果来看,有特征错误不会超过百分之二十,有兴趣的朋友可以根据自己的经验评估一下。

基本的单元测试方法有几种:人工静态分析(代码走查)、自动静态分析、自动动态测试,人工动态测试。

人工静态分析:程序员交叉查看对方的代码以检查错误,可能发现有特征错误和无特征错误。

自动静态分析:使用工具扫描代码,根据某些预先设定的错误特征,发现并报告代码中的可能错误,自动静态分析只能发现语法特征错误。

自动动态测试:使用工具自动生成测试用例并执行被测试程序,通过捕捉某些行为特征(如产生异常/程序崩溃/内存未释放等)来发现并报告错误,自动动态测试只能发现行为特征错误。

人工动态测试:人工设定程序的输入和预期的正确输出,执行程序,并判断实际输出是否符合预期,如果不符合预期,自动报告错误。这里所说的“人工”,仅指测试用例的输入和预期输出是人工设定的,其他工作可以由人工完成,也可以借助工具自动完成。人工动态测试可以发现有特征错误和无特征错误,例如,前面所说的加法函数,只要人工建立一个测试用例,输入两个1,并判断输出是否等于2,一运行测试,立即可以发现错误。

以上四种方法还可以进一步细化,这里就不详述了。那么,工作中是不是四种方法不分轻重都做一遍呢?显然不行,项目期限和预算不会允许这么做,也不符合效益原则,应该选择一种方法为主,其他视情况取舍。那么选择哪种方法为主呢?当然要选择有可能完成彻底测试的方法。自动静态分析、自动动态测试显然不可能完成彻底测试,它们只能发现有特征错误,这种说法对于希望用自动工具完成单元测试的朋友来说是一盆冷水,但没办法,因为这两种方法加起来,做到最好也仅限于发现有特征错误,而多数语法特征错误编译器就能发现,很多行为特征错误会在开发及集成测试和系统测试中自动暴露出来,所以这两种方法做单元测试的实际功效是很低的。人工静态分析虽然可能发现有特征错误和无特征错误,但是要彻底找出所有错误来,显然太难了。

最后剩下人工动态测试,这种方法有可能完成彻底测试吗?有一种说法是,“测试总是不彻底的”,对于软件整体来说,要做到彻底测试确实很难,但对于局部代码,则是完全可能的。先说 “理想的彻底测试”,对于一段程序,比如一个函数,如果它的所有可能输入都测试过,并且都没有错误,那么可以肯定,这个函数是没有错误的,这就是 “理想的彻底测试”。 “理想的彻底测试”是做不到的,有没有 “现实的彻底测试”?有!“现实的彻底测试”就是所有的等价类都经过测试并且都没有错误。

先说说等价类。“类”是指把输入数据分组,“等价”是指测试效果上的等价,“等价类”就是在一组输入数据中,任取一个进行测试,如果测试通过,那么,可以认为同组的其他输入数据也可以测试通过,也就是说,测试了一个,就等于测试了一组。如果把输入数据准确完整地划分等价类,并且所有等价类都通过测试,那么,就相当于所有输入都经过测试并且都没有错误,因此可以肯定,被测试代码是没有错误的,这就是“现实的彻底测试”。

对于一段程序来说,“等价类”通常是有限的,因此,从理论上来说,“现实的彻底测试”是完全可能的,但要实现彻底测试,就要在有限的时间内“准确完整地划分等价类”,这是一篇大文章,仅靠人力是不行的,借助于工具可以实现比较彻底的测试,后面再作详细介绍。

在经过人工动态测试后,其他测试方法还要不要再做呢?这就要看合不合算了。自动动态测试还是可以做的,因为它通常不会误报,也不需要花费多少人工,如果有遗漏的错误让它捕捉到,那就是好事一桩,如果没有,也不会耽误多少时间。自动静态分析就没有必要了,因为现有的自动静态分析技术会产生大量的误报,而编译器本身就会报告大部分的语法特征错误,又经过比较彻底的人工动态测试,真正的语法特征错误会极少极少,在一大堆报告中去一条一条人工辨别,效费比是很低的,有这个时间,还不如用在人工动态测试上,让人工动态测试更彻底些。至于人工静态分析(代码走查),如果某个错误连人工动态测试都没有发现,要想通过代码走查找出来,恐怕相当于大海捞针了,所以也不主张再进行代码走查,不过,可以偶尔抽查,主要检查代码风格是否符合规范。

经过人工动态测试后,不主张再做人工静态分析和自动静态分析,那么,先做这两项又怎么样?这就好像为了捕捉池塘里的鱼,可以买个鱼杈杈靠近边上的大鱼来捕捉一部分,也可以织个能覆盖整个池塘的大网来个一网打尽,鱼网可以代替鱼杈,但鱼杈不能代替鱼网,如果要捕捉全部的鱼,有没有必要先买个鱼杈再织个鱼网呢?当然,不会织网,或织出来的网破漏百出,那又另当别论,但可以肯定的是,无论如何,仅靠鱼杈是捕不完池塘里所有鱼的。后面的长篇大论,主要讲的就是织网的原理、方法与工具。

[ 本帖最后由 dellfox 于 2006-10-30 10:09 编辑 ]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

  • TA的每日心情
    奋斗
    2015-11-17 09:09
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]测试连长

    2#
    发表于 2006-10-30 21:34:28 | 只看该作者
    关注ing。。。
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-23 01:00 , Processed in 0.070175 second(s), 27 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表