为了让测试代码正确链接到桩函数,一般来说,要让函数具有与原函数相同的原形,这样就产生了一个问题:原函数与桩函数冲突。打桩过程中必须解决这个问题。
在实际工作中,打桩可以分两步来完成:
一、隔离测试任务,补齐未实现代码。可以利用IDE的链接错误来判断哪些函数需要打桩。例如,一个项目有1000个源文件,某位工程师需要测试其中的50个源文件,可以用IDE建立一个工程,将这50个源文件加入并编译,然后根据“符号未定义”链接错误,判断需要打桩的函数或全局变量,并编写桩代码。由于测试任务以外的源文件被隔离,这一步不会产生桩函数与原函数的冲突。
二、在测试过程中,视需要编写实现控制功能的桩代码。如果桩代码已经在上一步中编写,只要修改其实现就行了,如果不存在,通常表示原函数未被隔离,这时可以用编译条件来区分原函数与桩函数,如:
#ifndef _UNITTEST int B() { //... return 0; } #else int B() { //... return 1; } #endif |
在测试时定义编译条件_UNITTEST。
这种方式简单实用,但会对产品代码造成一些污染。
减少打桩工作的思路
一、采用自底向上的开发策略,先开发和测试底层代码,当测试上层代码时,假设底层代码是正确的,直接调用底层代码,从而减少打桩。
二、在隔离测试任务时将源文件分为三类:被测文件、外围文件、隔离文件。被测文件是指测试任务内的源文件;外围文件是指不测试或由其他人测试,但与被测文件关系密切的源文件;其他文件为隔离文件。外围文件与被测文件一起进行编译链接,测试时调用实际代码,从而减少打桩。
三、使用自动化工具。编写以隔离和补齐为目的的桩,是一种简单重复的工作,由工具生成最为合适。至于控制目的的桩代码,工具无法自动生成,但是,工具可以提供更为先进的方式,如底层模拟。底层模拟可以让桩输出像参数一样,在用例中设定,从而大幅减少单元测试的时间成本。
相关链接: