C/C++test完成测试工程配置后,就可以针对工程、源文件或指定测试用例执行单元测试。实际测试时,运行失败并不一定发生在测试用例本身,源码插桩、测试可执行文件构建、外部函数链接、运行环境和测试数据都可能让任务提前停止。碰到测试用例没有执行、构建阶段报错或者执行结果直接显示Failed时,把失败位置先分清,再去处理对应配置,通常比反复修改测试用例更容易找到问题。
一、C/C++test怎么执行单元测试
1、从Test Case Explorer运行测试用例
已经生成测试套件和测试用例时,可以直接从测试用例树选择执行范围。
①打开【Parasoft】→【Show View】→【Test Case Explorer】。
②展开测试工程,找到对应的【Test Suite】。
③继续展开测试套件,检查需要执行的【Test Case】是否已经存在。
④测试整个套件时直接选中【Test Suite】;只测试一个场景时,选中对应【Test Case】。
⑤右键选中的测试对象,进入【Test Using】。
⑥选择【Built-in】→【Unit Testing】→【Run Unit Tests】。
⑦等待测试可执行文件完成构建和运行。
⑧测试结束后回到【Test Case Explorer】,绿色项目表示测试通过,红色项目表示执行失败。
想测试整个工程,也可以在【Project Explorer】中选中工程后运行【Run Unit Tests】。如果只针对某个源文件做隔离测试,则选择【File Scope】下的【Run Unit Tests】。
2、运行前先做一次测试构建
项目依赖较多时,可以把“能不能构建测试程序”和“测试结果对不对”分开检查。
①选中要测试的工程或源文件。
②打开【Parasoft】→【Test Using】→【Built-in】→【Unit Testing】。
③选择【Build Test Executable】。
④只测试当前文件时,改用【File Scope】→【Build Test Executable】。
⑤打开【Console】查看编译和链接过程。
⑥确认没有头文件缺失、未定义符号和链接错误后,再执行【Run Unit Tests】。
如果试验构建都没有通过,直接运行单元测试通常还是会停在构建阶段,先处理编译和链接问题更省事。
3、缺少外部函数时生成Stub
被测函数调用了工程外部接口,而测试程序又找不到对应定义时,可以使用Stub补齐测试环境。
①打开【Test Case Explorer】,选中测试工程或目标文件。
②进入【Test Using】→【Built-in】→【Unit Testing】。
③先执行【Collect Stub Information】收集可替换的函数和变量信息。
④打开【Stubs】视图,检查缺失的外部符号。
⑤需要自动创建Stub时,运行【Generate Stubs】。
⑥打开生成的Stub,给函数设置测试需要的【Return Value】或输出行为。
⑦重新执行【Build Test Executable】。
⑧构建正常后再运行【Run Unit Tests】。
单文件隔离测试更容易出现未定义符号。这时可以使用【File Scope】对应的Stub收集和生成配置,只处理当前测试范围。
二、C/C++test单元测试运行失败如何定位
1、先看失败发生在哪个阶段
C/C++test单元测试从源码处理到结果输出会经过多个环节,失败位置不同,处理方法也不一样。
①打开【Console】。
②从测试日志开头往下找第一处Error,不要只看末尾的Failed提示。
③出现编译错误时,检查【Compiler Settings】、头文件路径和宏定义。
④出现链接错误时,重点找【undefined reference】或【unresolved symbol】。
⑤测试程序已经启动后才退出,再检查具体测试用例和运行时错误。
⑥测试长时间没有返回时,查看是否出现Timeout或执行超时信息。
工程刚配置完成就大量报编译错误,可以右键工程进入【Properties】→【Parasoft】→【C/C++test】→【Build Settings】,核对测试使用的编译器和原项目是否一致。
2、处理链接阶段的Unresolved Symbol
这是单元测试构建失败里比较常见的一类。
①在【Console】中找到报错的函数或变量名称。
②确认该符号是否由工程中的其他.c或.cpp文件提供。
③检查提供定义的源文件有没有包含在当前测试范围。
④如果使用【File Scope】测试,确认这个外部接口是否需要Stub。
⑤执行【Collect Stub Information】,再到【Stubs】中查找该符号。
⑥无法链接真实实现时,为它建立Stub。
⑦重新执行【Build Test Executable】,确认链接错误已经消失。
如果测试需要真实调用工程里的其他模块,就不要把所有外部函数都做成Stub,可以把提供真实定义的文件加入测试构建范围。
3、测试程序能运行但Test Case显示Failed
这种情况说明测试程序已经构建起来,问题已经进入测试结果判断阶段。
①在【Test Case Explorer】找到红色的测试用例。
②双击打开对应【Test Case】。
③查看输入参数和初始化数据。
④检查【Expected】中的预期结果。
⑤对比运行产生的【Actual】结果。
⑥函数涉及全局变量时,检查测试前后的全局变量值。
⑦涉及指针、数组或结构体时,确认测试数据长度和初始化内容没有填错。
⑧修改测试数据后,只选中当前【Test Case】重新执行,确认结果变化。
预期值写错也会让测试显示Failed,这和程序运行崩溃不是一回事,排查时不要混在一起处理。
三、单元测试反复运行失败怎么继续排查
1、用Debug Unit Tests定位代码位置
普通运行只能看到用例失败时,可以换成调试执行。
①在【Test Case Explorer】选中失败的测试用例。
②右键进入【Test Using】→【Built-in】→【Unit Testing】。
③选择【Debug Unit Tests】。
④在被测函数入口或怀疑异常的位置设置断点。
⑤启动调试后逐步执行代码。
⑥观察输入参数、局部变量、指针和全局变量。
⑦找到实际结果开始偏离预期的位置,再回到测试用例修改输入、Stub或预期值。
只调试当前文件时,可以使用【File Scope】下的【Debug Unit Tests】缩小测试范围。
2、检查测试执行超时和异常退出
测试程序一直卡着不结束,可以从运行过程继续找。
①打开【Console】,查看最后执行到哪个测试用例。
②单独选择该【Test Case】运行一次。
③检查被测代码里有没有死循环、无限等待或阻塞调用。
④外部通信、硬件访问等函数无法在当前测试环境执行时,可以改用Stub。
⑤检查测试配置中的【Execution】和【Runtime】相关设置。
⑥测试本身运行时间较长时,再检查当前执行超时限制是否合适。
程序出现崩溃、abort或者访问非法地址时,也可能拿不到完整的测试结果。此时更适合用【Debug Unit Tests】观察退出前的调用位置。
3、清理测试缓存后重新构建
编译参数、源码路径或Stub已经修改,运行结果却一直没变化时,可以清理旧测试数据再试。
①右键工程进入【Properties】→【Parasoft】→【C/C++test】。
②检查【C/C++test Temporary Files】使用的位置。
③确认没有其他测试任务正在运行。
④清理需要重新生成的临时测试数据。
⑤返回工程执行【Refresh】。
⑥重新运行【Build Test Executable】。
⑦构建通过后再执行【Run Unit Tests】。
工程工具链刚调整过、切换代码分支或者修改了大量测试配置时,重新构建一次也能避免旧测试文件继续影响当前结果。
总结
C/C++test单元测试运行失败时,编译、链接、测试执行和结果校验属于不同的问题,报错位置找准以后,处理范围会小很多。工程工具链、外部依赖和测试数据保持一致,测试用例本身也更容易稳定复用。对于反复失败的测试,可以结合单用例执行和调试模式找到具体代码位置,再决定修改测试环境还是被测程序。如需进一步了解C/C++test单元测试执行、Stub配置与测试失败排查方法,欢迎联系咨询。