目前,C++Test內建的单元测试分为两类
- 基于文件系统的测试结果收集
- 基于串口通讯的测试结果收集(串口通讯基于固件库)
在windriver环境中,其通常能够使用socket通讯方式回收结果,而目前的针对windriver的测试配置均为基于文件系统的,在某些没有文件系统的环境中无法进行测试。ps:目前遇到3个客户为这样的情况。
让C++Test通过网口收集测试结果的流程:
- 修为socket通讯
- 通过构建选项修改
- 手动编译运行时库方式修改
- 修改测试执行流
- 初始化网口(如需要)
生成socket通讯的运行时库 #
构建选项自动化生成运行时库 #
a) 构建选项->编译器设置,添加宏定义 -D CPPTEST_USE_UNIX_SOCKET_COMMUNICATION 指定C++Test使用socket通讯方式
其它支持的宏:
CPPTEST_USE_FILE_COMMUNICATIONS
CPPTEST_USE_FILE_SPLIT_COMMUNICATIONS
CPPTEST_USE_FILE_BUFFERED_COMMUNICATION
CPPTEST_USE_UNIX_SOCKET_COMMUNICATION
CPPTEST_USE_WIN_SOCKET_COMMUNICATION
CPPTEST_USE_RS232_WIN_COMMUNICATION
CPPTEST_USE_RS232_UNIX_COMMUNICATION
CPPTEST_USE_RS232_STM32F103ZE_COMMUNICATION
CPPTEST_USE_CUSTOM_COMMUNICATION
b) 修改测试执行流确保自动构建运行时库
<BuildRuntimeLibStep ignoreDbgOpts="true" autoBuildDefault="true" />
如果没有找到对应字段表明该字段为default值,default为true
c) 修改编译器选项(非必须)
对于主机平台的编译器,C++Test內建提供了便已完成运行时库,并且该运行时库在编译器模板中直接添加到链接中,将导致上述配置无效,因此需要修改编译器配置文件。
选择对应编译器添加自定义编译器->修改gui.properties,找到link命令,删除其中的 -L、-l 选项对应字段或类似runtime.a字样,避免其直接链接內建的运行时库。
手动编译运行时库 #
- 找到安装路径根目录下的engine\runtime 文件夹,拷贝一份为runtime_socket
- 打开makefile文件,修改CHANNEL_TYPE:=file 为 CHANNEL_TYPE:=unix-socket;修改TARGET_CFG:=gcc-static.mk 为 TARGET_CFG:=xxx.mk(对应编译器)
- 通过make构建运行时库,如果遇到报错请调试编译过程通常是由于头文件路径不正确导致,通过 -I 选项指定路径
- 修改构建设置,直接将手动编译生成的运行时库链接
- 修改编译器选项(非必须)
- 对于主机平台的编译器,C++Test內建提供了便已完成运行时库,并且该运行时库在编译器模板中直接添加到链接中,将导致上述配置无效,因此需要修改编译器配置文件。
- 选择对应编译器添加自定义编译器->修改gui.properties,找到link命令,删除其中的 -L、-l 选项对应字段或类似runtime.a字样,避免其直接链接內建的运行时库导致重定义或编码格式不匹配问题。
注意:该运行时库的实现是基于linux/unix标准系统库的,如嵌入式环境中系统库不同,需要定制运行时库来实现通讯。
修改测试执行流 #
添加ip、port属性 #
添加host、results_port、coverage_port属性用于配置C++Test地址,测试结果传输端口,覆盖率结果传输端口,uiEditable属性决定是否可以在界面中编辑
<SetProperty key="host" value="127.0.0.1" uiEditable="true" />
<SetProperty key="results_port" value="2567" uiEditable="true" />
<SetProperty key="coverage_port" value="2568" uiEditable="true" />
```

### 修改testrunner属性
使用TestRunnerWithSocketsGenerationStep代替TestRunnerGenerationStep,具体配置如下:
<TestRunnerWithSocketsGenerationStep
testSuiteConfigFile="${cpptest:testware_loc}/testsuites.xml"
testrunnerCFile="${cpptest:testware_loc}/cpptest_testrunner.c"
testrunnerCppFile="${cpptest:testware_loc}/cpptest_testrunner.cpp"
resultsHost="${cpptestproperty:host}"
testLogPort="${cpptestproperty:results_port}"
covLogPort="${cpptestproperty:coverage_port}"
/>
### 添加执行属性运行listener监听收集结果日志
ExecuteTestsExecution 属性为执行属性,因此本步骤及以下步骤的添加均为ExecuteTestsExecution的子属性。另外配置中所运用的均在安装路径根目录下的engine\runtime\listeners 中找到对应实现。
<CustomStep
id="run_socket_listeners"
label="Running Socket Listeners..."
commandLine=""java" -cp "${cpptest:cfg_dir}/../runtime_socket/listeners/socket_listener"
SocketListener --channel "${cpptestproperty:results_port}@${cpptest:testware_loc}/cpptest_results.tlog" --channel "${cpptestproperty:coverage_port}@${cpptest:testware_loc}/cpptest_results.clog"
-sf "${cpptest:testware_loc}/sync_file" -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="true"
/>
runInBackground="true" 设置该进程为后台运行,这将导致直接执行测试并结束测试,读取日志为空,需要通过Synchronize步骤来告诉C++Test测试还未结束等待获取结果
-to 为 timeout的简称用于设定超时时间
红字部分可能需要根据实际情况做更改
### 添加执行属性运行Synchronize执行测试
<CustomStep
id="run_synchronization"
label="Running Synchronization..."
commandLine=""java" -cp "${cpptest:cfg_dir}/../runtime_socket/listeners/socket_listener"
Synchronize -sf "${cpptest:testware_loc}/sync_file.init" -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="false"
/>
用于告诉C++Test可以进行下一步测试,并生成sync_file.init文件
### 添加测试运行属性run_test_exec
```
添加执行属性运行Synchronize 结果收集完成 #
id="run_synchronization"
label="Running Synchronization..."
commandLine=""java" -cp "${cpptest:cfg_dir}/../runtime_socket/listeners/socket_listener"
Synchronize -sf "${cpptest:testware_loc}/sync_file.final" -to 60"
workingDir="${cpptest:testware_loc}"
result="${cpptest:testware_loc}/cpptest_results.res"
runInBackground="false"
/>
生成sync_file.final文件,告诉listener已经同步结束,日志同步完成
注意 #
上述过程中不包含项目烧录过程,如遇到嵌入式环境可以尝试将上述步骤拆分为手动操作,验证完成之后添加对应测试执行流完成自动化测试。