为了让测试代码正确链接到桩函数,一般来说,要让函数具有与原函数相同的原形,这样产生了一个问题:原函数与桩函数冲突。打桩过程中必须解决这个问题。

  在实际工作中,打桩可以分两步来完成:

  一、隔离测试任务,补齐未实现代码。可以利用IDE的链接错误来判断哪些函数需要打桩。例如,一个项目有1000个源文件,某位工程师需要测试其中的50个源文件,可以用IDE建立一个工程,将这50个源文件加入并编译,然后根据“符号未定义”链接错误,判断需要打桩的函数或全局变量,并编写桩代码。由于测试任务以外的源文件被隔离,这一步不会产生桩函数与原函数的冲突。

  二、在测试过程中,视需要编写实现控制功能的桩代码。如果桩代码已经在上一步中编写,只要修改其实现行了,如果不存在,通常表示原函数未被隔离,这时可以用编译条件来区分原函数与桩函数,如:


#ifndef _UNITTEST
int B()
{
      //...
      return 0;
}
#else
int B()
{
      //...
      return 1;
}
#endif


  在测试时定义编译条件_UNITTEST。

  这种方式简单实用,但会对产品代码造成一些污染。

  减少打桩工作的思路

  一、采用自底向上的开发策略,先开发和测试底层代码,当测试上层代码时,假设底层代码是正确的,直接调用底层代码,从而减少打桩。

  二、在隔离测试任务时将源文件分为三类:被测文件、外围文件、隔离文件。被测文件是指测试任务内的源文件;外围文件是指不测试或由其他人测试,但与被测文件关系密切的源文件;其他文件为隔离文件。外围文件与被测文件一起进行编译链接,测试时调用实际代码,从而减少打桩。

  三、使用自动化工具。编写以隔离和补齐为目的的桩,是一种简单重复的工作,由工具生成为合适。至于控制目的的桩代码,工具无法自动生成,但是,工具可以提供更为先进的方式,如底层模拟。底层模拟可以让桩输出像参数一样,在用例中设定,从而大幅减少单元测试的时间成本。