• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

防御性编码和单元测试“交通规则”

发布: 2009-3-31 10:21 | 作者: 不详 | 来源: 测试时代采编 | 查看: 42次 | 进入软件测试论坛讨论

领测软件测试网

试着使用与其他组件或者程序交互的代码路径。如果其他程序或者组件还不存在,那么就自己编写一些脚手架代码以使您可以试用 API 或者填充共享内存、共享队列,等等。并让您的功能测试小组可以使用这个脚手架代码,这样他们就可以把它加入到他们的武器库中。

对于 GUI 中的每一个输入字段,试验下面多种不同的组合(考虑自动化):

不可接受的字符(控制字符、非打印字符等)。 过多的字符。 过少的字符。 负数(特别是当您只期待正数时)。 过大和/或者过小的数。 剪切和粘贴数据和文本到输入字段,特别是当您编写的代码限制用户可以键入该字段的内容时。 文本和数字的组合。 全大写字母和全小写字母。

为代码创建“压力条件”,如大量活动、慢连接的网络和所有您想到的可以将代码推到极限条件的东西。

反复进行同样的步骤,然后: 检查未预计到的内存损失条件。 检查当内存用光时发生什么。 试图创建缓存溢出、满队列、不可用的缓存以及其他“不能正确工作”的情况。对于数组和缓存,试着向数组(或者缓存)增加n个数据项,然后试图删除n+1个项。

关于时间的考虑?
如果操作“b”在操作“a”之前发生会怎么样?就算您认为它不会发生 —— 您能使它发生吗?如果是的话,可以打赌您的客户会使它发生的。最好现在找出来,而不是在修复成本更高、并听到客户报怨您的软件质量糟糕之后再去做。

脚手架代码
我们在前面发现缺陷中讨论了脚手架代码。如果是为自己的使用需要而创建的,一定要将它交给验证工程师。可能您提供的脚手架代码使他们可以很快地开始测试您的代码,或者至少使他们更好地理解当其他组件存在时可以预期什么。

如果您的产品有保护性的安全功能,那么您必须测试它们。提供可以创建您想要防止的情况的脚手架代码是很重要的:您必须能够创建系统试图防止的那种情况。

脚手架代码的另一个简单例子是提供操纵队列的代码。如果您的产品使用队列,那么想像如果有一个可以在运行时从队列中增加或者删除项、破坏队列中的数据(以保证适当的错误处理)等等的工具会有多方便。

源代码级调试程序
使用源代码级的调试程序是进行彻底和成功的单元测试的关键方法。开发人员应该与他们的调试程序共生死。不幸的是,对源代码级的调试程序的充分了解和使用是一种正在消亡的做法,尽管这些调试程序的好处远远超过任何学习曲线。简而言之,我们强烈鼓励您全面学习一种调试程序。下面是用源代码级调试程序对代码进行单元测试的几种方法。您可以:

在运行中操纵数据 —— 例如,在输入代码时设置中断点,然后重新设置传递的参数值以检查代码是否能正确处理(现在为)无效的参数。以这种方式使用调试程序就不需要让错误条件真正发生。

设置断点,然后“单步”通过代码,这样您就可以看到每一行代码所做的事情。

设置对变量的“监视(watch)”。

强制使用错误代码路径。

观察调用堆栈以检查哪一个例程调用了您的代码。

在错误发生时“捕获”它们。

执行边界检查。

认识您的验证工程师
验证工程师是测试知识的很好来源。他们可以给您指出要测试什么并帮助您了解可以在代码中加入什么以帮助他们测试(如代码钩子)。此外,您可以向他们展示如何使用您的脚手架代码。他们还会很有兴趣了解您认为在测试中哪些应该是自动化的 —— 如果您某些事情做了不止一遍,那么他们也会。

开始测验!
现在是进行小测试的时候了。让我们看看您是否用心了。

问题
您希望检查一个整数的值是否为5。通常,要这样编写代码:

if ( i == 5 ) then { // // do something... // }

不过,如果您对代码进行“手指检查”,并且把代码写成了下面这样会出现什么情况呢?

if ( i=5 ) then { // // do something... // }

这个失误是一个缺陷,但是只有在运行时才能捕获它 —— 可能需要相当的调试努力才能找到它。编译器会轻易放过您的代码,那么如何防止这种错误发生?

答案
实际上有两个答案:您可以使用一种上面描述的静态代码分析工具,并希望它有足够的健壮性可以捕获这种错误,也可以交换操作数以使常量位于左边:

if ( 5 == i ) then { // // do something... // }

因为这种方法保证您可以在编译代码时立即捕捉到问题,所以它是首选的技术。虽然它看上去有些笨,但是代码可以编译并运行得很好。然而,当您“手指检查”代码时就可以立即看到好处了:

if ( 5=i ) then { // // do something... // }

可是编译器不喜欢这样,因为5不能被赋值为另一个值。这就是我们在前面说您应当将编译器看成是您的朋友时所表达的意思。

您还可以在检查 null 指针时使用这个技巧。看下面的代码:

if ( returnString == null ) { // // do something... // }

如果您偶然将它“误写”成下面这样会发生什么呢?

if ( returnString=null ) { // // do something... // }

您可能不会得到想要的结果。而改用下面的方法您会得到与我们刚描述过的同样的“编译器保护”:

if ( null == returnString ) { // // do something... // }

结束语
您可能预计会有一个长的小结,把我们所讨论的所有内容重新概述一遍,然后是请您尽可能多地采用我们的建议。冒着让您失望的风险,为保持简明扼要我们做了一个相当简洁的归纳:要么现在去做,要么以后花多得多的代价去做。换句话说,您在开发周期的早期在测试和预防代码缺陷上花的时间越多,您在以后节省的时间和金钱就越多。这就是防御性编码的意义。它就是这么简单。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

55/5<12345

关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网