5.2 选择合适的应用时机
所谓覆盖率分析的应用时机,是指在软件开发生命周期中的什么阶段进行应用比较合适。依笔者个人看法,要看具体的需求,就覆盖率工具的引入只要有代码后,无论哪个阶段都可以。下面是常见的一些应用场景:
1)单元测试阶段:由于单元测试是对软件最小单元的函数或类的测试,是直接对代码进行的测试,覆盖率的使用比较普遍。但大家不要有误区,认为只有单元测试才能进行代码覆盖率测试。
2)集成测试阶段,软件正在持续构建中,分期分模块引入覆盖率工具,验证集成测试的成熟度是否符合预期。
3)系统测试阶段,可以一次性集中进行,也可分模块分批进行。如果是手工执行用例,建议在系统测试的中后期(版本比较稳定)时进行巩固测试(回归测试)时进行。
在笔者所经历的项目应用中,我们是在版本已趋于稳定,集中资源进行一次巩固测试(回归测试)时引入,有如下收获与建议:
1)当成回归测试动态执行用例,而不是为了得到覆盖率数据而随意点击界面,或无序地执行用例;
2)某一阶段集中一些资源集中做一件事,效率高,在得到覆盖率数据时,同时还巩固测试了软件,也发现了一些bugs;
由于我们想得到系统功能测试对代码的覆盖情况,而系统测试的大部分用例在当时并未自动化,一轮遍历完成所有用例,耗时还是较多的。居此,想到两点可以改进的建议(提高测试效率),一者是自动化执行用例,同时得出代码覆盖率信息;二者是只考虑核心模块、风险较大模块进行覆盖率分析。
覆盖率分析应用中,难免会发现一些bugs,由于此时的测试对象已集成了覆盖率工具,软件在运行过程中难免会受到一些干扰,建议将一些有怀疑的bug在未插入覆盖率工具的软件上进行确认,以排除覆盖率工具的影响。
6、总结与思考
在历经项目覆盖率分析的整个过程中,笔者一直都在思考着一些问题:
◆ 能帮我们什么,不能帮我们什么?
这个问题有点大,但通过在项目中的应用,一路走过来后,有以下收获:
1)100%的覆盖率,是一种理想状况,即便达到100%的覆盖,并不意味着软件就无bug(就可以回家睡大觉,安枕无忧了)。覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好了这些代码,比如讲述语句覆盖的案例中列举的除零Bug问题。
2)较低的测试覆盖率能说明我们的测试还不够,反之是不成立的。
3)在任何时候高覆盖率都比低覆盖率好,这一点无可否认,但软件测试作为一种商业活动行为,我们需要顾及软件的整体质量及成本。
4)无论何时,覆盖率都是评估测试质量的重要指标之一。
5)越高的代码覆盖率,只能代表完整性(即我们测试过哪此代码),而不是充分性(即测好了这些代码)。因为完整性代表的是一个测试宽度的概念,而充分性是一个表示测试深度的概念。充分性是用户场景、系统状态、模块接口等相关的用例执行是否足够,状态、边界、异常、容错等处理是否都已组合考虑到位。
6)代码覆盖率可以帮我们发现测试遗漏,但不能直接改进测试。
在笔者项目应用的实际情况中,最后通过分析补充的用例150条,覆盖率提高了2.5%(比较少)。这给我们一个这样的启示:目前我们系统测试的全面性已达上限(或接近上限),如何进行另一幅度的提高,需要寻求另一种改进方法。例如:防御性代码占比高,如何覆盖到它们,孤函数占比高,这部分代码又该如果优化?
代码覆盖率仅仅能够告诉我们什么没有被测试,根本就回答不了软件是否经过了有效测试!
◆ 如何提高测试覆盖率的进一步思考
未覆盖的代码,防御代码占比高,是我们这次覆盖率分析工作的主要话题,如何解决这个问题,是一个共性的问题,下面提出一种可行的解决方案:
采用软件故障注入技术,是一个不错的方法,但是不是唯一的方法,肯定不是,也希望感兴趣的同学一起来分享你的想法。话又说回来,未覆盖到的代码,是否值得提高其覆盖度。软件故障注入技术,结合未覆盖到的代码,具体如何做,已超出本文讨论的主题。
1)未执行到的代码,有一大部分是孤代码,此部分代码如何处理?如果不优化它们,覆盖率受到很大影响。
2)难于模拟出错的场景去覆盖防御性代码?如fopen(),fread(),malloc() 这些函数的返回值,正常情况下一般不会返回为NULL,但规范的编程中必须对这种情况进行防御,一旦出现这种情况时,程序能回到一种活着的状态,要知道对于软件来说进入死机、崩溃,用户是难于接受的。
3)想来想去,覆盖率只能作为一种评估测试过程的手段,对测试质量的贡献有限。如果要解决的问题是提高软件质量,建议转向ET(探索性测试),始终围绕用户场景,有针对性地进行专项测试,在对软件质量的贡献上效果应会更好。
版权声明:51Testing软件测试网原创出品,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明,否则将追究法律责任。