更新时间:2021年12月24日15时15分 来源:传智教育 浏览次数:
源代码插桩是指对源文件进行完整的词法、语法分析后,确认插桩的位置,植入探针代相比于目标代码插桩,源代码插桩具有针对性和精确性。源代码插桩模型如图3-4所示。
图3-4 源代码插桩模型
从图3-4可以看出,源代码插桩是在程序执行之前完成的,因此源代码插桩在程序运行过程中会产生探针代码的开销。相比于目标代码插桩,源代码插桩实现复杂程度低。源代码插桩是源代码级别的测试技术,探针代码程序具有较好的通用性,使用同一种编程语言编写的程序可以使用一个探针代码程序来完成测试。
上面讲解了源代码插桩的概念与模型,为了让读者理解源代码插桩的使用,下面通过一小案例来讲解源代码插桩。该案例是一个除法运算,代码如下所示。
# include < stdio.h > # define ASSERT(y) if (y) { printf("出错文件:%s\n", __FILE__);\ Printf("在第%d行:\n") __LINE__\); printf(” 提示: 除数不能为0!\ n ");\ } //定义ASSERT(Y) int main(){ int x, y; printf( "请输入被除数:"); scanf("%d", & x); Printf( "请输入除数:"); scanf("%d", & y); ASSERT(y == 0); //插入的桩(即探针代码) printf("%d", x / y); return 0; }
为了监视除法运算除数输入是否正确,在代码第13行插入宏函数ASSERT(y),当除数为O时打印错误原因、出错文件、出错行数等信息提示。宏函数ASSERT(y)中使用了C语言标准库的宏定义“▁FILE▁”提示出错文件、“▁LINE▁”提示文件出错位置。程序运行后,提示输入被除数和除数在输入除数后,程序宏函数ASSERT(y)判断除数是否为0,若除数为0则打印错误信息,程序运行结束;若除数不为0,则进行除法运算并打印计算结果。根据除法运算规则设计测试用例,如表下表所示。
对插桩后的C源程序进行编译、链接,生成可执行文件并运行,然后输入表3-8中的测试用例数据,读者可观察测试用例的实际执行结果与预期结果是否一致。程序插桩测试方法有效地提高了代码测试覆盖率,但是插桩测试方法会带来代码膨胀、执行效率低下和HeisenBugs,在一般情况下插桩后的代码膨胀率在20%~40%,甚至能达到100%导致插桩测试失败。
HeisenBugs即海森堡Bug,它是一种软件缺陷,这种缺陷的重现率很低,当人们试图研究时Bug会消失或改变行为。实际开发软件测试中,这种缺陷也比较常见,例如,测试人员测试到一个缺陷提交给开发人员后,开发人员执行缺陷重现步骤却得不到报告的缺陷,因为缺陷已经消失或者出现了其他缺陷。