C/C++ test中文网站 > 使用教程 > C/C++ test测试桩怎么生成 C/C++ test测试桩返回值怎么模拟
教程中心分类
C/C++ test测试桩怎么生成 C/C++ test测试桩返回值怎么模拟
发布时间:2026/06/04 11:34:37

  在动手写单元测试的时候,我们常常碰到这样一种情况:被测的函数里会去调用数据库、操作硬件接口、读写文件、走网络通信,或者用到了一些还没开发完的底层模块。假如直接在测试里让这些真实的依赖跑起来,测试环境就很难被控制住,也不太容易稳定地把那些异常分支给复现出来。所以在C/C++test这个工具里,就需要搞清楚两件事:测试桩到底该怎么生成,以及桩的返回值要怎么去模拟。基本上的思路就是,先用一个桩把外部的函数给替换掉,然后再根据不同的测试用例,去设置正常的返回值、错误码、超时的表现,或者多次调用时每次返回什么不同的结果。C/C++test既支持我们自己手写桩,也可以让工具自动生成,而且一旦建了用户自定义的桩,它的优先级是比原始函数和自动桩更高的。

  一、C/C++test测试桩怎么生成

 

  要生成测试桩之前,得先让工具把我们项目里的那些函数符号给认出来。要是打开Stubs窗口后,发现里面空空的没有函数列表,先别着急手工去写桩,而是要先收集一下符号信息。

 

  1、打开Stubs窗口

 

  从Parasoft的菜单里找到【Show View】,再点进【Stubs】,就能把桩的窗口调出来。如果这是头一次打开,窗口里可能会显示一条提示,说符号数据还没有收集(Symbols data not collected)。这时候,先把我们要测试的那些源文件给选中,然后跑一下Collect Stub Information这个动作,或者去Build Test Executable的配置里跑一遍,工具就会把函数和变量的符号都给收集过来。

 

  2、缺少实现的时候生成Auto Stub

 

  如果项目中某个函数只有声明,找不到实际的实现,那就可以在Stubs列表里,对着这个函数的名字点右键,选上【Generate Auto Stub】。工具会帮我们自动生成一个桩文件,把函数的定义给补上,同时也把需要的头文件引用给加进去。如果有好几个缺失的函数,也可以一次把它们全选中,批量生成。

 

  3、需要主动替换时创建User Stub

 

  要是原始函数本身就存在,但我们测试的时候不想真正去调它,比如说不想访问硬件,或者不想真的去删除文件,那就可以右键这个函数,选择【Create User Stub】。这种用户自定义桩的优先级更高,就算原始实现还好端端地摆在那里,测试执行的时候也会优先走我们自己写的桩。

 

  4、检查桩文件的输出目录

 

  自动生成的桩最后落到哪里去,可以在Stubs窗口的【Stub settings】里头设置。要是这个自定义的目录不在项目默认的路径下,那还得进到测试配置的【Execution】→【Symbols】里,把桩文件所在的目录加到附加符号来源里面去,这样工具才能认得它们。

 

  二、C/C++test测试桩返回值怎么模拟

 

  桩函数生成出来之后,最好不要让所有的测试用例都共用同一个一成不变的返回值。正常情况、异常情况,还有边界情况,都需要分别去设置,这样才能让不同的代码分支都被覆盖到。

 

  1、在测试用例里加上Stub Configuration

 

  打开测试用例的编辑器,可以在里面添加一个新的步骤,叫Stub Configuration。在这个步骤里,先选好我们要模拟的是哪一个函数,然后再把想要的返回值或者输出参数给设置进去。C/C++test在跑这条用例的时候,就会去执行对应的桩逻辑,不用我们每次都手工去改动那个主桩文件。

 

  2、按照不同用例去模拟不同的结果

 

  打个比方,某个接口函数顺利执行时可以返回0,连接失败的时候就返回一个负数,超时的时候返回一个特定的错误码。把每一个用例要用的返回值分开配置,这样做不仅测试结果更容易复核,而且也不会因为改动了公共的桩文件,就干扰到其他的用例。

  3、模拟多次调用的结果

 

  有时候,同一个函数在一次测试里会被不止一次地调用,比如说第一次我们希望它返回成功,第二次希望它返回失败。用Stub Callback就可以根据一个叫callNo的次数变量,来给它设置每次不一样的返回值。这种回调方式还可以访问到函数传进来的参数,以及返回值的指针,所以很适合用来模拟重试、超时或者状态变化这一类的情况。

 

  4、用数据源来批量驱动返回值

 

  如果需要覆盖很多组的错误码,或者很多个边界值,就可以先建一个数据源,然后在桩函数里,根据数据源的某一列来读取值。C/C++test是支持在桩里面去查询数据源列的,并且能读出整数、字符串这些类型的数据。这样一条用例就可以批量地验证好多组输入,以及桩给回来的不同结果了。

 

  三、C/C++test测试桩不生效怎么排查

 

  要是桩都已经生成好了,可执行的时候发现测试还是在跑真实的函数,这通常和桩的优先级、插桩的模式,或者符号有没有刷新到位有关系。

 

  1、检查Instrumentation mode

 

  进到测试配置的【Execution】→【General】里,确认一下当前用的模式是不是Full、Full runtime w/o coverage之类的,或者是一种自己定制的、包含了桩插装功能的模式。如果没有把桩插装给打开,那就算桩文件好端端地摆在那里,也是不会按我们预期的样子生效的。

 

  2、确认用的是什么类型的桩

 

  自动桩的优先级相对较低,要是原始函数确实存在,有时候可能仍然会去调原始的实现。如果真的需要强行替换掉,那就得用User Stub;另外,如果是测试外部的库函数,还可以去检查一下Function stubs mode,看看是不是需要把它设成Stub all calls。

 

  3、刷新符号,再看看有没有冲突

 

  我们手工添加或者删掉桩文件之后,Stubs窗口里的列表不一定自己就能刷过来。这个时候可以把符号收集的配置重新跑一遍,然后再去看看列表里的Definition列。要是发现同一个函数有好几个用户桩,窗口里就会显示一个conflict,这时候就得把重复的定义给删掉。

 

  4、复核一下回调注册的位置

 

  在用Stub Callback的时候,一定要在调用被测函数之前,就把回调给注册好。要是注册的代码写到了被测函数执行之后,那当前用例仍然会按照默认的桩逻辑来走,不会去跑我们写好的回调。

  总结

 

  总的来说,在C/C++test里生成测试桩,常用的路径就是先打开Stubs窗口,收集好符号,然后根据不同的场景去选择是用Generate Auto Stub还是Create User Stub。而要让桩返回我们想要的值,可以在测试用例里面直接添加Stub Configuration来设定,也可以通过Stub Callback来模拟多次调用和动态返回的结果。如果发现桩没有按预想的起作用,那就优先去查一下插桩的模式对不对、桩的类型选没选对、符号有没有及时刷新,以及有没有出现重复定义的情况,不要一上来就反复去改动被测的代码。这样一步步排查,通常就能让桩稳稳地接管那些外部依赖了。

135 2431 0251