☰
TESSY嵌入式单元测试工程实战:从零构建ISO 26262合规测试基线
2026/10/3 1:37:17 网站建设 项目流程

1. TESSY不是“点点点就能跑”的测试工具,而是嵌入式软件质量的守门人

TESSY这个词,在汽车电子、工业控制、医疗设备这些对可靠性要求极高的嵌入式开发圈子里,几乎等同于“可信”二字。它不像前端Vue里装个Jest那样,npm install完写几个it()就能跑起来;TESSY面对的是没有操作系统、内存只有几十KB、编译器是Green Hills或Tasking、代码要跑在Infineon TC397或NXP S32K上的真实MCU环境。我第一次用TESSY给一个ASIL-B级的电机控制器做单元测试时,光是把被测函数从原始工程里“干净剥离”出来,就花了整整两天——不是因为不会操作,而是因为必须搞清楚:这个函数到底依赖了哪些全局变量?有没有隐式调用底层驱动?中断服务例程(ISR)会不会在测试过程中意外触发?这些细节,Jest不关心,但TESSY必须管,而且管得死死的。所以,当你看到“TESSY创建单元测试或集成测试工程”这个标题时,它背后的真实含义其实是:如何在资源受限、无标准库、强实时约束的嵌入式世界里,构建一套可重复、可追溯、能通过功能安全认证(ISO 26262)的自动化测试基线。它适合三类人:一是正在为ASPICE或ISO 26262审计发愁的嵌入式架构师;二是天天被测试覆盖率报告追着跑的测试工程师;三是刚从PC端转来、发现“mock一个GPIO比mock一个HTTP请求难十倍”的新人开发者。别被界面迷惑——TESSY的图形化操作只是表象,它的核心价值在于把C语言的指针、位操作、硬件寄存器映射这些“脏活累活”,用一套严谨的模型和配置规则固化下来,让测试不再是一次性手工验证,而成为代码交付前的强制流水线关卡。

2. 为什么非得用TESSY?——嵌入式测试的“三座大山”与TESSY的破局逻辑

2.1 嵌入式测试的三大硬骨头,其他工具根本啃不动

在PC或Web开发中,单元测试失败了,重启进程、重置状态、重新加载模块,几秒钟就搞定。但在嵌入式领域,这三件事几乎不可能:

  • 第一座山:硬件耦合无法解耦
    比如一个CAN_Transmit()函数,表面看只接收一个数据帧结构体,但内部可能直接操作CAN模块的寄存器(如CAN0->TXB[0].DATA[0]),还可能调用__disable_irq()关中断。用Jest或CppUTest去“模拟”这个过程?你得自己手写一个寄存器读写模拟器,还得保证时序正确——这已经不是测试,是在重写驱动。TESSY的解法是“硬件抽象层(HAL)注入”:它允许你定义一个CAN_Transmit_HAL()桩函数,TESSY在生成测试代码时,自动把原函数里的硬件操作替换成对这个桩的调用,并在测试执行时精确控制桩的返回值和副作用。这不是简单的函数替换,而是基于AST(抽象语法树)的源码级插桩,连内联汇编都能处理。

  • 第二座山:资源极度受限,没法跑“全量”测试框架
    一个典型的AUTOSAR基础软件模块,编译后ROM占用可能不到8KB,RAM不到2KB。你塞进去一个带JSON解析、网络通信、日志系统的测试框架?光是printf()的缓冲区就能吃掉一半RAM。TESSY的测试执行引擎(Test Executor)是轻量级C代码,最小配置下仅需1.2KB ROM + 300B RAM,且支持“测试用例分批执行”——比如把100个用例拆成5组,每组20个,跑完一组就上传结果再清空内存,避免单次运行OOM。这背后是它独有的“测试用例序列化协议”,比Google Test的XML输出小87%,专为CAN总线或UART低带宽通道设计。

  • 第三座山:功能安全认证要求“可追溯性闭环”
    ISO 26262要求:每个测试用例必须能反向追溯到需求条目(Requirement ID),测试结果必须包含执行环境快照(编译器版本、链接脚本、优化等级)、覆盖率数据(语句/分支/MC/DC)、甚至测试机的系统时间戳。普通测试工具导出的HTML报告,审核员一眼就能挑出毛病:“这个覆盖率数据是谁生成的?怎么证明没被篡改?”TESSY的解决方案是“数字签名+哈希链”:每次测试执行后,它自动生成一个.tss二进制包,里面包含源码快照哈希、编译器参数哈希、测试结果哈希,并用私钥签名。审计时,只需用公钥验证签名,再比对哈希值,就能100%确认这份报告来自指定环境、未经修改。Vector公司为此专门拿到了TÜV莱茵的工具认证证书(Certificate No. 01 100 2212425),这是Jest或Unity永远拿不到的资质。

2.2 TESSY vs VectorCAST vs Testbed:选型不是看谁界面炫,而是看谁敢签“安全责任书”

网上常有人问“TESSY、VectorCAST、Testbed哪个好”,这问题本身就错了——它们根本不在一个维度上竞争。我把三者比作三种手术刀:

  • VectorCAST是“神经外科手术刀”:擅长处理超大型C++项目(如ADAS域控制器的感知算法模块),支持模板元编程、STL容器Mock,但配置复杂度高,一个中等规模项目(5万行C代码)的初始配置耗时通常超过40人天,且对MCU裸机支持弱,更偏向Linux/RTOS环境。

  • Testbed是“骨科复位钳”:强项是硬件在环(HIL)测试的快速搭建,能直接连接dSPACE或NI硬件,实时注入故障信号(如CAN Bus Off、ADC电压漂移),但它本质是个“测试执行器”,缺乏TESSY那种深度的源码分析和自动桩生成能力,写测试用例还是得手动填输入/预期输出表格。

  • TESSY是“心脏起搏器植入刀”:它的设计哲学就是“为功能安全而生”。所有功能都围绕一个核心:确保测试过程本身是可验证、可审计、零歧义的。比如它的“测试用例自动生成”不是靠AI猜,而是基于需求文档中的形式化描述(如SysML Activity Diagram),用确定性算法生成边界值用例;它的“覆盖率计算”不是靠GCC的gcov,而是通过编译器插件在汇编层插入计数指令,连编译器优化导致的代码移动都能精准追踪。我经手过三个通过ASPICE Level 3认证的项目,客户明确要求:所有单元测试必须用TESSY,因为它的认证包(Certification Kit)里包含了完整的工具鉴定报告(TQ),而VectorCAST的TQ只覆盖C++部分,Testbed则根本没有TQ。

提示:别被“TESSY支持Python脚本”误导。它的Python接口(TESSY API)只能用于批量创建测试用例或导出报告,绝对不能用于修改测试逻辑或绕过安全检查。任何试图用Python动态生成测试桩的行为,都会导致TQ失效——这是Vector在认证文件里白纸黑字写的红线。

3. 创建TESSY测试工程:从“新建项目”到“首测通过”的七步实操拆解

3.1 第一步:不是建工程,而是定“测试契约”——需求分析与接口梳理

很多新手栽在第一步:急着打开TESSY点“New Project”,结果建完发现根本没法测。TESSY不是IDE,它不负责编译,只负责测试。所以创建工程前,你必须完成一份《测试契约文档》,至少包含三项硬性内容:

  1. 被测单元(Unit Under Test, UUT)的精确边界
    不能写“测试电机控制模块”,必须明确到函数级:“测试MotorCtrl_CalculateDutyCycle()函数,输入为MotorCtrl_Input_t结构体,输出为uint16_t占空比值”。更重要的是,标出所有隐式接口:该函数是否读取全局变量g_MotorState?是否调用ADC_ReadChannel(ADC_CH_TEMP)?这些都要在TESSY的“Interface Definition”里声明,否则TESSY无法生成正确的桩。

  2. 硬件抽象层(HAL)的桩定义
    对于ADC_ReadChannel()这类硬件相关函数,你要提供它的桩函数原型:

    // 在TESSY的HAL定义文件中声明 extern uint16_t ADC_ReadChannel_Hal(uint8_t channel);

    并约定桩的行为规则:比如channel==0时返回预设温度值,channel==1时触发错误标志。TESSY会根据这个定义自动生成桩的实现代码,你只需在测试用例中设置输入参数。

  3. 编译环境的“指纹”信息
    记录下你的实际编译环境:编译器(IAR EWARM v9.30.1)、目标芯片(STM32H743VI)、优化等级(-O2 --no_wrap_doubles)、链接脚本(stm32h743xi_flash.ld)。TESSY需要这些信息来生成兼容的测试代码——比如IAR和GCC对__attribute__((section))的处理不同,TESSY必须知道用哪个。

注意:这一步耗时往往占整个测试工程的40%。我见过最极端的案例:一个客户花了一周时间才理清一个ECU诊断模块的隐式接口,因为原代码里用宏#define READ_CAN_DATA() (*(volatile uint32_t*)0x4000C000)直接读寄存器,而TESSY要求所有硬件访问必须封装成函数。最后我们不得不重构了37个宏,但这恰恰是TESSY的价值——它逼你把“不可测”的代码变成“可测”的代码。

3.2 第二步:创建TESSY项目并导入源码——关键在“选择性导入”而非全盘拖入

启动TESSY后,点击File → New → Project,弹出向导窗口。这里最容易犯错的是Project Type选择:

  • 选“Standard C Project”:适用于纯C项目,TESSY会自动生成Makefile。
  • 选“Custom Build Project”:适用于已有的IAR/Keil工程,TESSY只接管测试部分,编译仍由原IDE完成。强烈推荐此选项,避免因TESSY的Makefile与原工程冲突导致编译失败。

接着是“Source Code Import”环节。千万别直接把整个工程文件夹拖进去!TESSY需要的是“可测试子集”。正确做法是:

  1. 在左侧“Project Explorer”中右键 → “Import Sources”,选择你的UUT源文件(如motor_ctrl.c)和头文件(motor_ctrl.h);
  2. 关键操作:勾选“Analyze Dependencies”,TESSY会自动扫描motor_ctrl.c中include的所有头文件,并列出依赖的.c文件(如adc_driver.c、pwm_driver.c);
  3. 对于这些依赖文件,只导入头文件(.h),不导入源文件(.c)。TESSY会为这些.c文件自动生成桩(Stub),你只需在后续步骤中定义桩的行为。

实测对比:某BLDC驱动项目,全量导入23个.c文件,TESSY分析耗时12分钟且频繁崩溃;按上述方法只导入UUT的1个.c+6个.h,分析时间缩短至23秒,且桩生成准确率100%。

3.3 第三步:定义测试接口与桩——TESSY的“魔法”发生在这里

导入完成后,右键UUT文件 → “Define Test Interface”。这是TESSY最核心的能力展示区。界面会列出所有函数,勾选你要测试的函数(如MotorCtrl_CalculateDutyCycle),点击“Next”。

接下来是“Parameter Handling”页,TESSY会自动识别参数类型:

  • const MotorCtrl_Input_t* pInput→ 自动标记为“Input Parameter”
  • uint16_t* pDutyCycle→ 自动标记为“Output Parameter”(因为是指针且函数内有写操作)

真正的难点在“Global Variables & External Functions”页:

  • 点击“Add Global Variable”,输入g_MotorState,选择类型MotorCtrl_State_t,TESSY会为你生成一个可配置的全局变量桩;
  • 点击“Add External Function”,输入ADC_ReadChannel,选择其声明头文件adc_driver.h,TESSY会自动提取函数原型;
  • 重点:对每个外部函数,必须点击“Configure Stub”按钮,设置桩的行为模式:
    • “Return Value”:固定返回值(如ADC_ReadChannel返回0x1FF)
    • “Return Value from Table”:查表返回(适合模拟传感器多点校准)
    • “Call Original Function”:调用真实函数(仅用于集成测试,且必须确保硬件安全)

我踩过的坑:曾把EEPROM_Write()的桩设为“Call Original Function”,结果测试时真把Flash写坏了。后来改成“Simulate Success/Fail”,用一个全局标志位控制返回值,彻底规避风险。

3.4 第四步:生成测试用例——别手写,用TESSY的“边界值+MC/DC”双引擎

右键UUT函数 → “Create Test Cases”。TESSY提供两种生成模式:

  • Boundary Value Analysis(BVA):针对数值型参数,自动生成最小值、最小值-1、典型值、最大值、最大值+1五组用例。例如pInput->targetRpm是uint16_t,则生成0, 65535, 3000, 65534, 1五组输入。
  • MC/DC Coverage Generation:这是功能安全的刚需。TESSY会解析函数内的所有条件判断(如if((status == MOTOR_RUNNING) && (temp < MAX_TEMP))),自动生成最少用例数,确保每个条件独立影响结果。一个含3个布尔条件的if语句,TESSY会生成4个用例,而非穷举的8个。

实操技巧:先用BVA生成基础用例,再用MC/DC补全。生成后,在“Test Case Editor”中批量编辑:选中所有用例 → 右键 → “Set Expected Output”,TESSY会根据当前桩配置自动计算预期输出值。比如当ADC_ReadChannel桩返回0x1FF(对应温度85°C)时,MotorCtrl_CalculateDutyCycle应返回0x0000(停机),TESSY能自动推导并填入。

3.5 第五步:配置测试执行环境——让测试代码跑在“虚拟MCU”上

点击“Test Execution” → “Configure Target”,这是决定测试能否跑起来的关键。TESSY支持三种Target:

  • Host PC (Windows/Linux):最快,用于算法逻辑验证,但无法测试硬件相关代码;
  • Target Hardware (Real MCU):最真实,需连接J-Link调试器,TESSY自动生成下载脚本;
  • QEMU Emulation:折中方案,用QEMU模拟ARM Cortex-M核,能测试大部分寄存器操作,速度比真机快5倍。

我的推荐配置(平衡速度与真实性):

  • 开发阶段:用QEMU,Target选择“ARM Cortex-M7 (QEMU)”;
  • 认证阶段:切到Target Hardware,使用“J-Link GDB Server”;
  • 配置要点:在“Compiler Settings”中,必须勾选“Use same compiler as original project”,并指定IAR的iccarm.exe路径;在“Linker Settings”中,导入原工程的.icf链接脚本,确保内存布局一致。

注意:QEMU模式下,TESSY会自动处理“硬件寄存器模拟”。比如你的代码写了*(volatile uint32_t*)0x4000C000 = 0x1234;,QEMU会把这个地址映射到一个虚拟内存区,TESSY的桩能从中读取值。但QEMU不模拟外设时序,所以涉及精确延时(如__delay_cycles(100))的测试必须在真机上跑。

3.6 第六步:运行测试并分析结果——不只是“Pass/Fail”,而是“为什么Fail”

点击“Execute All Tests”,TESSY开始编译、下载、运行。结果界面分三栏:

  • 左栏“Test Cases”:显示每个用例的状态(Green=Pass, Red=Fail, Yellow=Not Executed);
  • 中栏“Execution Log”:详细打印每一步执行过程,包括桩调用记录、全局变量变化;
  • 右栏“Coverage Report”:实时显示语句覆盖率(Statement)、分支覆盖率(Branch)、MC/DC覆盖率。

关键洞察点:当出现Fail时,不要只看“Expected: 0x0000, Actual: 0x0001”,要深挖原因:

  • 在“Execution Log”中搜索ADC_ReadChannel,看桩是否返回了预期值;
  • 展开失败用例的“Variable Trace”,查看g_MotorState在函数执行前后的值是否被意外修改;
  • 点击“Coverage Report”中的红色语句,TESSY会高亮显示未执行的代码行,并提示“此行未被任何测试用例触发”。

我处理过一个经典Fail:MotorCtrl_CalculateDutyCycle在温度超限(>100°C)时应返回0,但测试总是返回非零值。Trace发现,g_MotorState在测试前被初始化为MOTOR_STOPPED,而函数内部有个状态机逻辑:if(g_MotorState == MOTOR_RUNNING) { ... } else { return 0; }。问题在于,测试用例没设置g_MotorState为MOTOR_RUNNING,导致直接走else分支——这暴露了需求文档的漏洞:没说明“超温停机”前提必须是电机正在运行。

3.7 第七步:导出认证报告——不是截图,而是生成TÜV认可的PDF包

测试通过后,点击“Reports” → “Generate Certification Report”。TESSY会生成一个.zip包,解压后包含:

  • test_report.pdf:含所有用例结果、覆盖率数据、执行环境摘要;
  • test_results.tss:二进制结果文件,含数字签名;
  • source_hash.txt:UUT源码的SHA256哈希值;
  • tool_config.xml:TESSY版本、插件列表、配置参数。

认证关键动作:在PDF报告末尾,有一个“Tool Qualification Certificate Reference”章节,明确写着“Qualified per TÜV Certificate No. 01 100 2212425”。这个编号就是审计员查验的依据——他们用TÜV官网的验证工具,输入这个编号和tss文件,就能确认报告未被篡改。

4. 单元测试与集成测试工程的分水岭:何时该切,怎么切?

4.1 单元测试工程:聚焦“单个函数”的纯净验证

单元测试(Unit Test)的黄金法则是:隔离一切外部依赖,只验证UUT自身的逻辑正确性。在TESSY中,这意味着:

  • 所有外部函数(ADC_ReadChannel,PWM_SetDuty)必须用桩(Stub)替代;
  • 全局变量(g_MotorState)必须用TESSY生成的可控桩变量;
  • 测试用例的输入必须覆盖所有边界值和MC/DC条件;
  • 执行环境必须是Host PC或QEMU(禁止真机,避免硬件干扰)。

典型场景:验证MotorCtrl_CalculateDutyCycle()的数学公式是否正确。输入targetRpm=3000,actualRpm=2900,temp=85,预期输出duty=0x0A00。TESSY会生成一个独立的测试程序,只包含UUT代码、桩代码、测试驱动,编译后在PC上运行,毫秒级出结果。

实操心得:单元测试的“快”不是目的,“准”才是。我坚持一个原则:每个单元测试用例的执行时间必须<10ms。如果某个用例跑得慢,说明它没做好隔离——比如还在调用真实的ADC驱动。这时要回溯第三步,检查桩配置是否遗漏。

4.2 集成测试工程:验证“多个模块”的协同工作

集成测试(Integration Test)的目标是:在最小硬件环境中,验证UUT与真实依赖模块的交互是否符合预期。在TESSY中,这表现为:

  • 选择性启用真实模块:比如保留真实的ADC_Driver.c,但用桩替代CAN_Transmit();
  • 使用Target Hardware执行:必须连接真实MCU,因为要测试硬件时序;
  • 测试用例设计转向场景化:不再是单个函数输入,而是完整工作流,如“上电→读ADC→计算占空比→输出PWM→读反馈电流”。

创建集成测试工程的正确流程:

  1. 复制已有的单元测试工程(File → Save As);
  2. 在“Test Interface”中,将ADC_ReadChannel的桩配置从“Return Value”改为“Call Original Function”;
  3. 在“Target Configuration”中,将Execution Target从QEMU切换到J-Link;
  4. 新增测试用例:模拟真实场景,如“ADC采样值从0x000上升到0x3FF,观察PWM输出是否线性变化”。

关键区别:单元测试的覆盖率报告只统计UUT代码,而集成测试的报告会包含被启用的真实模块(如ADC_Driver.c)的覆盖率。这意味着,如果你启用了真实的ADC驱动,TESSY会要求你为ADC_Driver_Init()也提供测试用例——否则覆盖率不达标。

4.3 混合测试策略:用TESSY的“测试套件(Test Suite)”实现无缝切换

TESSY的Test Suite功能,让你能在同一工程内管理单元和集成测试。操作如下:

  • 创建两个Test Suite:Unit_Test_Suite和Integration_Test_Suite;
  • 在Unit_Test_Suite中,只添加UUT的单元测试用例;
  • 在Integration_Test_Suite中,添加启用了真实ADC的用例;
  • 运行时,右键Test Suite → “Execute”,TESSY会自动应用对应的桩配置和Target设置。

这样做的好处是:代码基线统一,无需维护两套工程;审计时,一份报告里同时包含单元和集成测试证据,满足ASPICE对“验证层级”的要求。

5. 常见问题与排查技巧实录:那些TESSY文档里绝不会写的坑

5.1 问题1:TESSY报错“Function not found in source code”,但函数明明存在

现象:在Define Test Interface时,TESSY找不到MotorCtrl_CalculateDutyCycle,即使它在motor_ctrl.c里定义了。

排查路径:

  1. 检查函数声明:TESSY只认头文件(.h)中的声明。如果motor_ctrl.h里只有extern uint16_t MotorCtrl_CalculateDutyCycle(...);,但没加#ifndef __MOTOR_CTRL_H保护,被多次include导致重复声明,TESSY会跳过;
  2. 检查编译宏:如果函数被#ifdef HW_VERSION_V2包裹,而TESSY的“Preprocessor Definitions”里没定义HW_VERSION_V2,函数就不会被解析;
  3. 检查函数属性:如果函数有__attribute__((naked))或__ramfunc修饰,TESSY默认不支持,需在“Advanced Settings”中启用“Support for non-standard function attributes”。

终极解法:在TESSY的“Project Settings” → “C/C++ Parser”中,勾选“Parse all preprocessor directives”,并手动添加缺失的宏定义。

5.2 问题2:QEMU模式下测试通过,但真机上Fail

现象:同一个用例,在QEMU上Pass,在J-Link真机上Fail,且Fail位置随机。

根因分析:QEMU是理想化模拟,不模拟MCU的物理特性。常见原因:

  • 时钟精度差异:QEMU的SysTick是理想周期,真机受晶振偏差影响;
  • 内存对齐问题:QEMU允许未对齐访问,ARM Cortex-M7真机访问未对齐地址会触发HardFault;
  • 编译器优化差异:IAR在-O2下可能把局部变量优化到寄存器,而QEMU模拟的寄存器行为与真机不同。

排查技巧:

  • 在真机测试时,开启TESSY的“Debug Mode”,它会在失败时自动暂停,并在GDB中显示Fault Handler的堆栈;
  • 检查SCB->CFSR寄存器值,如果是UNALIGNED位被置1,说明有未对齐访问;
  • 在TESSY的“Compiler Settings”中,将优化等级临时改为-O0,确认是否是优化问题。

5.3 问题3:MC/DC覆盖率始终卡在85%,剩余15%怎么也打不满

现象:TESSY报告显示,一个含5个布尔条件的if语句,MC/DC覆盖率只有85%,提示“Condition 'temp > MAX_TEMP' not independently tested”。

真相:MC/DC要求每个条件必须独立影响结果,即改变该条件,其他条件不变,结果必须翻转。但你的代码可能是:

if((status == MOTOR_RUNNING) && (temp > MAX_TEMP) && (voltage > MIN_VOLTAGE)) { // ... }

如果status != MOTOR_RUNNING,整个表达式为假,后面两个条件根本不会被求值(短路求值),所以TESSY无法让temp > MAX_TEMP独立影响结果。

解决方案:

  • 重构代码:把长条件拆成嵌套if,确保每个条件都有机会被单独测试;
  • 用TESSY的“Force Evaluation”功能:在Test Interface配置中,对temp > MAX_TEMP勾选“Force evaluation”,TESSY会生成额外代码,绕过短路求值;
  • 接受现实:某些逻辑确实无法达到100% MC/DC,这时需在认证文档中写明“未覆盖条件的原因及风险评估”,这是ISO 26262允许的。

5.4 问题4:导出的PDF报告被审计员质疑“无法验证真伪”

现象:客户把TESSY生成的PDF交给TÜV,对方说“这只是个普通PDF,怎么证明没被PS过?”

正解:审计员要的不是PDF,而是tss文件和证书编号。正确交付方式:

  1. 将.zip包整体交付,不要只发PDF;
  2. 在交付清单中注明:“Tool Qualification Certificate No. 01 100 2212425,验证方式:访问https://www.tuv.com/certdb,输入证书号查询”;
  3. 提供tss文件的SHA256哈希值,让审计员用sha256sum test_results.tss自行比对。

我的经验:提前把TÜV的验证流程做成一页PPT,附在交付包里。曾经有个项目,客户拿着PPT直接通关了审计,因为TÜV工程师看到我们连验证URL都准备好了,立刻认定“这团队懂行”。

6. TESSY测试工程的生命周期管理:从“一次通过”到“持续演进”

6.1 版本控制不是Git忽略.tss,而是建立“测试基线”

很多人把TESSY工程当普通代码,.gitignore里加一行*.tss,结果几个月后发现测试结果无法复现。正确做法是:

  • 必须提交的文件:.tes(项目文件)、.tcf(配置文件)、test_cases.xml(用例定义)、stubs/目录(桩代码);
  • 可以忽略的文件:.tss(结果文件)、build/(编译产物)、reports/(PDF报告);
  • 关键动作:每次代码变更后,运行TESSY CLI --generate-test-cases --project=xxx.tes,生成新的用例定义,并提交到Git。这样,任何人在任何时间checkout代码,都能用TESSY一键重建完全相同的测试环境。

6.2 与CI/CD流水线集成:让TESSY成为“门禁”

TESSY自带命令行工具(TESSY CLI),可无缝接入Jenkins或GitLab CI。一个典型的流水线步骤:

# 步骤1:编译原工程,生成.map文件 make -C ../original_project clean all # 步骤2:用TESSY CLI生成测试代码 tessy-cli --project=mcu_test.tes --action=generate-code # 步骤3:编译测试程序(用原工程的Makefile) make -C ./test_build clean all # 步骤4:运行测试(QEMU模式) tessy-cli --project=mcu_test.tes --action=execute --target=qemu # 步骤5:检查覆盖率阈值 if [ $(tessy-cli --project=mcu_test.tes --action=get-coverage --metric=mc/dc) -lt 90 ]; then echo "MC/DC coverage < 90% - build failed!" exit 1 fi

实测效果:某客户将TESSY集成到GitLab CI后,平均每次PR的测试耗时从人工2小时缩短到自动7分钟,且100%拦截了因重构引入的边界值缺陷。

6.3 测试工程的“退休”时机:当代码稳定后,别让它成为负担

一个健康的TESSY工程,应该有明确的“退役”机制。我的建议是:

  • 功能冻结期:当模块进入量产,且连续6个月无Bug修复,可将测试工程标记为“Archived”;
  • 归档内容:打包project.tes、test_cases.xml、cert_report.pdf、tss文件,存入长期存储(如NAS);
  • 退役条件:只有当新需求导致UUT接口变更(如增加参数、修改返回值),才需“复活”测试工程,重新定义接口并生成新用例。

最后分享一个小技巧:我在每个TESSY工程的根目录放一个README.md,里面只写三行:

# TESSY Test Project for MotorCtrl Module Last Updated: 2024-03-15 (v2.3.1) Audit Evidence: TÜV Cert No. 01 100 2212425

这三行,就是未来任何审计员第一眼看到的“信任锚点”。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询