
1. 先还原现场这个“Work function丢失”到底是什么问题1.1 现象描述Tessy 4.0打开旧版本创建的测试用例时Work function丢失这是升级工具链后相当常见的一个坑。很多团队还在用3.x甚至更早的Tessy维护测试资产某天因为合规要求或者编译器升级不得不切到Tessy 4.0结果一打开工程发现之前辛辛苦苦维护的测试用例还在但每个用例里关联的被测函数全部变成了空引用。具体表现有三种典型形态打开工程后测试用例列表正常显示但点击某个用例界面底部的Work function区域显示为空白或“Invalid”。用例还在但函数名被标成红色/黄色右键也无法跳转到源码头文件。尝试编译测试环境时直接报错提示找不到函数定义或声明Harness生成失败。这里要解释一句Work function不是函数本身而是Tessy里连接“测试用例”和“被测源码”的那条映射关系。可以把它理解成一根线一头拴着你在界面里填的输入参数、桩函数设置、期望输出另一头拴着源码里真实存在的那个c函数。线一旦断了用例就变成了一堆没有落点的数据等于废了。最让人头疼的是这条线什么时候断的、为什么断的Tessy本身通常不会给你明确提示。有时候打开工程时只弹一个“reference broken”的警告有时候连警告都没有等跑到执行阶段才发现所有用例都跑不起来。1.2 容易踩坑的场景我实际处理过的项目里最容易触发这个问题的场景有这么几类第一类是换机器迁移。开发机从A换到B源码路径从D:\work\project_a\src变成C:\code\new_project\src但Tessy工程里记录的Work function引用还是旧的绝对路径。4.0打开时找不到源码直接就丢映射。第二类是代码仓库结构调整。比如原来被测函数在/src/module_a/util.c重构后挪到了/common/utils/util.c。函数本身没改名但整个目录树变了。Tessy不是靠符号名全网搜索的它依赖工程里记录的源文件路径和文件内符号偏移路径一变它就不认得这个函数了。第三类是升级过程中操作顺序错。有人直接在4.0里双击打开3.x的工程文件让工具自动做转换。大部分时候它能转过来但转换逻辑对旧的工程配置文件存在兼容盲区尤其是涉及集成测试的多层Test Unit结构时容易出现部分Work function掉链子。第四类和编译器环境有关。Tessy 4.0对新版编译器的预处理指令支持更严格如果旧工程里用的宏定义、#ifdef分支和4.0的解析规则冲突源码解析阶段就可能把某些函数判定为“不可达”进而丢掉Work function映射。如果你遇到的是上面这几种情况别急着重建用例绝大多数情况下映射是可以恢复的。下面从根因讲起然后给一套完整的处理路径。2. 为什么会丢根因排查思路2.1 版本差异带来的数据模型变化Tessy 4.0对工程文件和数据模型做了不少调整。老版本里Work function通常和Function直接绑定引用方式比较直白。4.0引入了更细的Test Unit概念区分了模块测试和集成测试的层级关系。打开旧工程时工具会做一次隐式的数据迁移把老的数据模型映射到新的模型结构里。这个映射过程不是100%可靠的。特别是有多层调用关系的集成测试用例——比如你测试的是函数A但A内部调用了B和C用例里同时配置了对B和C的桩设置——迁移时如果B和C的解析顺序不对就可能只保留了A的Work function引用B、C丢失或者整体全部丢失。4.0的项目文件沿用XML结构但Schema版本和旧版本不兼容。我拆过转换前后的工程文件对比过最大的差异在于老版本把被测函数信息直接嵌在每个TestCase节点下新版本则把函数引用统一提到Test Unit级别TestCase通过ID关联。这个“提级”操作在转换时要是没匹配上TestCase底下的Work function自然就成了孤儿引用。2.2 路径引用断裂最常见的物理原因Work function丢失的物理原因九成以上是路径引用断裂。Tessy工程里记录源码文件位置时有一个“路径快照”机制创建测试用例时会把当时的源码绝对路径、文件修改时间、函数在文件中的大致位置记录进工程数据库。之后如果发生以下任一种情况映射就会失效工程文件被拷贝到新机器源码没有按原路径摆放。源码文件被移动、重命名或者整个目录被合并。版本控制系统切换了工作目录的盘符或路径前缀。用共享目录/网络盘时挂载点变了比如从\\server\share\src变成\\server2\share\src。路径中含中文或空格迁移到大小写敏感的文件系统后路径匹配失败。这个机制本身是为了提高Tessy的加载速度避免每次打开都全量扫描源码。但代价就是路径一旦变了工具不能自动纠正只能显示引用失效。2.3 源码解析层面的隐性因素还有一类丢失不是路径问题而是解析问题。Tessy在判断“某个函数是不是我要找的那个函数”时会做一次源码级校验包括函数签名、参数个数、头文件引用方式。如果旧工程创建时使用的头文件和现在的不一致——比如原来void foo(int a);后来改成void foo(int a, int b);或者把参数类型从int改成uint32_t——Tessy在解析时发现签名对不上就会判定当前源码中不存在匹配的函数Work function引用跟着就丢了。这类问题最迷惑人因为从代码上看函数明明还在文件路径也对但在Tessy的逻辑里它已经“找不到”这个函数了。另外如果源码里用了较新的C语言标准特性比如_Generic、复杂的#pragma指令而Tessy 4.0的源码解析器配置没有相应更新解析过程会在预处理阶段静默失败同一文件里的函数引用全部丢失。这种情况在从老版本工具链切换到新版本时尤其常见因为4.0的默认解析器策略可能比旧版更严格。2.4 数据库残留造成的半迁移状态最后一种容易被忽略的根因是数据库残留。Tessy的工作目录里除了工程文件还有缓存数据库、测试结果数据库、桩函数配置等。4.0打开旧工程时如果工作目录里存在旧版本生成的中间缓存且缓存格式不再被4.0支持工具会在缓存与工程文件之间存在数据不一致。在这种情况下Work function的引用信息可能只存在于旧缓存里新工程转换时没有迁移这部分数据最后表现出来就是用例列表能看到列表从工程XML加载的函数名信息丢失从旧缓存加载失败。排查时可以打开.olly或.log日志搜索“work function”或“function reference”关键字通常能找到具体是在哪一步丢失的。日志里如果出现DB schema mismatch或者loader error基本可以判定是缓存数据库的问题而不是代码本身的问题。3. 对症下药完整恢复与迁移方案3.1 事前备份清单动手之前先做这一步不少同事一看到Work function丢失立刻去工具里手动重新映射。如果是少量用例这么干还行几百上千个用例手点是不现实的。更稳妥的做法是搞清楚自己的工程里有哪些东西可以备份先把后路留好。需要备份的核心文件有四类文件类型典型路径/后缀作用工程文件项目根目录下的.prj、.tess文件保存工程配置、路径定义测试数据.tdb、.tessdb或XML导出的用例保存测试用例的业务数据模块定义.mod、.xml的模块描述保存模块分组、函数列表环境配置.tcf/编译器配置、环境变量设置保存编译和解析环境对于尚未打开的旧工程优先在旧版本Tessy里做一次“导出”。Tessy 3.x支持导出成可移植的XML压缩包通常叫Export Test Data这个包会把所有测试用例连同函数引用信息打包成相对路径格式。拿到4.0里导入成功率比直接打开工程高很多。如果没有旧版本Tessy了那么至少把整个工程目录原样复制一份不要只复制工程文件。一定要连同.metadata、.cache之类的隐藏目录一起复制这些看起来不起眼的文件夹里往往存着函数引用索引。3.2 推荐路径通过导入功能完成迁移直接双击打开旧工程是最省事但也是最容易出问题的方式。我的建议是走导入链路具体步骤在Tessy 4.0中新建一个空白工程选择与旧工程相同的目标编译器配置。在菜单栏选择File - Import - From Existing Project。选择旧工程文件Tessy会弹出导入向导。关键一步导入选项中勾选Import Test Cases and References同时确认Create backup before conversion是启用状态。完成后打开导入的工程检查Work function引用情况。这个导入链路和直接打开的核心区别在于导入过程会重新做一次源码路径解析把相对路径重新映射到当前环境的实际位置。直接打开则基本沿用旧工程里记录的路径快照路径一变就失效。导入完成后如果部分Work function仍然丢失不要立刻手动重建先检查导入日志。在导入摘要页面通常有明细列表会列出“无法解析的函数”。跳转到这个列表把源码路径修正后重新执行Update References即可。3.3 手动重新映射Work function对于导入后仍然丢失的少量函数可以用手动映射方式修复。操作入口在Tessy 4.0的Test Unit视图下定位到丢失的函数右键选择Properties。找到Work Function Mapping区域。点击Browse在弹出的源码文件浏览器中定位到对应的.c文件。确认函数名和签名匹配保存。这里面有个容易被忽略的细节Tessy的映射对话框中不仅要选择源文件还要确认“头文件引用”。函数名一样但头文件不一致Tessy可能在后续的Test Environment生成阶段仍然报错。手动映射适用于几十个量级的修复。如果要处理几百个用例建议用下面介绍的批处理方式。3.4 用批处理和命令行模式做批量修复Tessy从4.0开始提供完整的命令行接口这是处理大规模映射丢失的最佳手段。我通常用两种方式第一种是利用Update References命令。在命令行模式下执行tessy -project 工程文件 -updateReferences -sourcePath 源码根目录 -logFile 输出日志这个命令会重新扫描指定源码路径尝试把工程内所有悬空的函数引用重新绑定。执行完成后查看日志确认有多少函数被成功恢复。第二种方式是导出再导入用-exportTestData把整个工程的测试数据导出成XML手动修正XML里的路径字段再用-importTestData导入。这种方式技巧性更强适合对Tessy数据格式有深入了解的人。批处理模式有几个好处可以写在脚本里统一执行不会漏执行过程有日志排查起来方便不需要打开图形界面在CI服务器上也能跑。3.5 临时绕行方案重建TestCase外壳如果时间紧迫、崩溃的引用实在修复不了还有一个临时方案保留用例的输入输出数据重新生成TestCase外壳。做法是在丢失Work function的Test Unit下新建一个同名的TestCase然后用Tessy的“Import Test Data”方式从丢失的用例里把输入参数、桩函数设置、期望输出导入进来。说白了就是函数映射丢了但用例里的数据还在把数据搬到新壳子里重新建立映射。这个方案比较费人工只适合少量关键用例的紧急修复。而且要注意丢失的如果是集成测试用例新壳子必须和原用例处于同一Test Unit层级否则搬过去的数据的桩函数配置可能对不上。4. 实操过程实录与关键步骤拆解4.1 步骤一用Tessy 4.0正确导入旧工程我以最近处理过的一个模拟项目为例项目代号叫“某电子控制模块”。这个项目使用的旧Tessy工程文件位于E:\work\ecu_control\tessy_project源码在E:\work\ecu_control\src。按前面说的导入路径操作导入完成后发现工程里12个Test Unit、800多个TestCase中有3个Test Unit下的136个TestCase出现Work function丢失。整体占比不算高但集中在几个和信号采集相关的模块里影响面很大。导入时注意一个细节Import From Existing Project向导里有一项Path Mapping Rules默认是空白的。如果旧工程中的源码路径和当前路径不一致建议在这里预填一条规则比如把E:\old_build\src映射到E:\work\ecu_control\src。这个规则能在导入阶段就完成路径修正可以省去后续手动修复的大量工作。4.2 步骤二定位丢失的Work function导入完成后进入测试环境视图我习惯按以下顺序排查缺口先看Test Unit层级是否有函数挂在“Unresolved”状态。检查“Test Interface”页签里函数的签名信息是否与源码一致。打开源码文件确认函数真实定义位置。在这个例子里排查发现136个丢失用例集中在两个函数signal_process()和fault_check()。源码都在函数签名也没变那问题在哪进一步检查发现这两个函数所在的源文件在最近一次代码重构中引入了#ifdef CONFIG_FAULT_DETECT条件编译。旧版Tessy在解析时默认开启了所有宏分支所以能看到函数定义而4.0的解析器只处理当前编译器配置下实际生效的宏分支没有启用对应宏时函数被整体藏进了未编译分支Tessy就直接判定为源码中不存在。这个发现把问题从“路径错误”转向了“解析宏设置”处理思路完全不同。4.3 步骤三修复与重新映射针对上述宏分支问题修复路径是调整编译器配置中的预处理宏。在工程属性里找到Source Code Preprocessor设置将CONFIG_FAULT_DETECT加入全局宏定义列表保存后重新执行源码同步。执行Update References后日志显示“134 of 136 references were resolved successfully”。剩余两个用例是因为函数签名里有一个参数类型从unsigned char改成了uint8_t——数值上等价但Tessy的严格匹配机制判定为签名不一致。对这两个用例用右键Properties打开映射对话框手动重新选择函数后保存。这里有个小技巧如果只是类型不一致可以在Tessy的Type Compatibility设置里开启“宽松类型匹配”把所有同宽度的整型视为等价类型。开启后这两个用例也能自动恢复不需要手动调整。4.4 步骤四回归验证Work function全部恢复后不能直接认为事情结束了。引用恢复只是让Test Environment可以生成逻辑上是否还有问题要靠回归来验证。回到工程根节点右键选择Generate Test Environment确保所有Test Unit都能成功生成Harness。生成成功后随机挑3个之前丢失函数的测试用例执行确认执行结果和旧版本的基准结果一致。如果执行结果不一致优先检查是不是映射到了同名但不同实现的重载函数。我碰到过一次源码里有process_data(int)和process_data(float)两个重载Tessy恢复时匹配错了导致用例执行通过但结果异常。排查方法很简单看执行日志里调用的是哪个地址或者在映射对话框里看选中的函数签名参数类型。回归验证还有一个隐藏环节桩函数。集成测试用例里配置的桩函数是挂在Work function底下的子节点。如果Work function只是路径恢复桩函数配置一般跟着走但如果用的是重建TestCase外壳那个方案桩函数配置多半要重新手动挂。这个点容易漏验证时一定要检查每个恢复的用例里桩函数的配置是否还在。5. 常见问题排查速查表与避坑心得5.1 高频问题速查现象直接原因处理方式打开工程后函数名标红路径引用断裂确认源码实际路径修正路径映射后Update References导入时报“module not found”工程中的模块定义与源码结构不匹配检查模块配置文件或从源码重新创建模块后导入测试数据Work function显示但执行时报错函数签名不匹配查看函数的头文件定义确认类型兼容性设置桩函数配置丢失多发生于重建TestCase外壳时手动重新关联桩函数或在导入时选择包含Stub数据的选项只有部分函数丢失条件编译宏不一致对比新旧编译器配置补齐预处理宏定义打开工程时无警告但执行时全部失败数据库缓存损坏停止加载删除缓存目录重新打开工程并同步源码命令行Update References无效工程文件被锁定或处于交互模式确认是否有其他Tessy实例占用工程关闭后重试源码路径含中文字符导致解析失败编码问题迁移源码到纯英文路径或调整Tessy的编码设置5.2 几条实操经验第一升级Tessy 4.0不是简单替换安装包的事。工程里每个模块用的编译器配置、解析宏、头文件路径都要重新核对一遍。Work function丢失只是表象背后是编译解析上下文整体变了。我建议升级前三方联调工具链负责人、源码构建负责人、测试负责人一起对齐编译器版本和全局宏定义能避免大半引用丢失问题。第二路径规划要提前做。Tessy对绝对路径的依赖程度高不要只在个人机器上测试。团队协作时固定的构建目录约定比什么都重要。一个可落地的做法是所有Tessy工程的源码路径统一用环境变量引用比如%PROJECT_SOURCE%而不是硬编码盘符。这样换机器时只需要改环境变量Work function的路径引用不会跟着断。第三定期做测试数据导出。不是等版本升级才导出而是在每次完成一轮功能回归后用Tessy的导出功能生成一个XML备份。这个备份文件是可移植的包含函数引用关系。平时可能觉得冗余但真遇到4.0打不开旧工程的情况时这个XML就是你救命的最后一张牌。第四升级后的前两周不要删除旧版本Tessy。新旧版本共存并不冲突旧版本主要负责看原始数据和对比新版本负责正常测试流程。过了稳定期再清理旧环境心理压力会小很多。我再把一个小技巧放在最后Tessy的工程文件虽然是XML结构但没必要手动编辑它。遇到映射问题时优先用图形界面的“Update References”和命令行批处理这两种方式都会Tessy内部统一处理数据一致性。手动改XML文件很容易把工程改崩我见过不止一次因为多加了半个尖括号导致整个工程无法加载的情况。回到Work function丢失这个问题上这么多处理方式里我认为最值得养成习惯的动作就是“变更前导出”。不管是升级工具、迁移代码还是换机器先把测试数据导出为便携格式再做任何操作。只要这个习惯养成了Tessy版本升级也好、目录重构也好都只是参考数据重新导入一遍的事情真正失控的概率就非常低了。