2. TestStand核心数据模型解析
在TestStand中,测试数据追溯能力并不是某个单独功能提供的,而是由Sequence、Step、Result、Report、PropertyObject这五个核心对象层层承载、逐级传递形成的。理解它们之间的映射关系,是设计可追溯测试系统的前提。很多追溯断链问题,本质上不是数据库或报表工具的问题,而是数据在模型层级之间没有被正确“挂接”或“落盘”。
五个核心对象的职责边界
Sequence是执行与组织的容器,它定义了测试流程的顺序、调用关系与执行入口。一个Sequence可以包含多个Step,也可以调用子Sequence。它本身不保存测量值,但决定了“谁在什么条件下被执行”。
Step是最小执行单元,也是追溯字段最自然的挂载点。每个Step有类型(如NumericLimitTest、StringValueTest、PassFailTest、SequenceCall等)、名称、唯一标识(Step ID/Unique ID)以及执行结果状态。Step是“做了什么测试”的语义载体。
Result是Step执行后产生的数据记录,包含测量值、判定结果、单位、上下限、时间戳等。Result是“测试得到了什么”的事实载体,也是追溯系统真正需要持久化的对象。
Report是Result的可读呈现,通常由TestStand内置报表生成器或自定义报表插件输出为HTML、XML、ATML、PDF等格式。Report不是数据源,而是数据的视图,因此追溯字段必须在Result阶段就写入,而不能等到Report阶段再补。
PropertyObject是TestStand的通用数据容器,Sequence、Step、Result、Station全局变量、FileGlobal等本质上都是PropertyObject。它支持层级结构、自定义属性、类型定义(Type Definition),是追溯字段能够被结构化存储的底层机制。
追溯字段应该挂在哪里
追溯字段包括产品序列号(SerialNumber)、操作员(OperatorID)、工位(StationID)、产品型号(ProductModel)、测试时间(TestTime)、夹具编号(FixtureID)、软件版本(SWVersion)等。这些字段的共同特点是:它们不是某一次测量的结果,而是描述“这次测试是在什么背景下发生的”。因此它们不适合放在单个Step的Result里,而应该放在Sequence的PropertyObject中,并在Result生成时被复制或引用到每条Result记录上。
推荐的做法是:在Sequence的Parameters或Locals中定义一组追溯字段,通过TestStand的StationGlobal或FileGlobal在运行时赋值,再通过Post-Step回调或Database步骤将这些字段与Result一起写入数据库。这样做的关键收益是:无论Sequence中有多少个Step,每条Result都携带完整的追溯上下文,不会出现“只有部分Step有序列号”的断链。
Result到Report的映射原则
Report是Result的投影,不是独立数据源。TestStand生成Report时,会遍历Sequence中的Step,读取每个Step的Result,再按模板渲染。因此,如果追溯字段只写在Report模板里,而没有写入Result或PropertyObject,那么数据库导出、MES对接、SPC分析都会丢失这些字段。正确的顺序是:先保证Result完整,再让Report去呈现Result。
在Report模板中,可以通过ThisContext或RunState访问Sequence的PropertyObject,从而把SerialNumber、OperatorID等字段渲染到报表头部。但要注意,这只是“显示”,真正的追溯数据必须已经在Result或数据库记录中。
PropertyObject的层级与类型定义
PropertyObject支持嵌套结构,例如Sequence.Locals.Traceability.SerialNumber。这种层级设计让追溯字段可以按业务域分组,避免命名冲突。更重要的是,TestStand支持Type Definition,可以把一组追溯字段定义为一个自定义类型,然后在多个Sequence中复用。这样当追溯字段需要增加(例如新增BatchID)时,只需修改类型定义,所有引用该类型的Sequence都会同步更新。
在实际项目中,建议把追溯字段分为三层:产品层(SerialNumber、ProductModel、BatchID)、设备层(StationID、FixtureID、SWVersion)、人员层(OperatorID、Shift)。这三层分别对应不同的数据来源和更新频率,分层存储后,数据库表结构也会更清晰。
一个可参考的追溯字段映射表
下表给出一个示例映射,字段名和来源可根据实际项目调整。表中“写入时机”指的是该字段应该在哪个阶段被赋值,而不是等到Report生成时才补。
| 追溯字段 | 建议挂载对象 | 数据来源 | 写入时机 | 用途 |
|---|---|---|---|---|
| SerialNumber | Sequence.Locals.Traceability | 扫码枪 / MES接口 | Pre-UUT回调 | 单件追溯主键 |
| ProductModel | Sequence.Locals.Traceability | MES工单 / 配置文件 | Pre-UUT回调 | 型号维度统计 |
| StationID | StationGlobal | Station配置 | 启动时加载 | 工位追溯 |
| FixtureID | StationGlobal / Sequence.Locals | 夹具识别电阻 / 手动输入 | Pre-UUT回调 | 夹具寿命与不良关联 |
| OperatorID | StationGlobal | 登录信息 / 工牌扫描 | 登录时写入 | 人员追溯 |
| SWVersion | Sequence.Locals.Traceability | 测试程序版本常量 | Sequence加载时 | 软件版本追溯 |
| TestTime | Result(自动生成) | TestStand运行时 | Step执行时 | 时间序列分析 |
常见断链场景与判断依据
如果数据库中出现SerialNumber为空、OperatorID缺失或FixtureID不一致,通常不是数据库写入失败,而是字段没有在正确的PropertyObject层级上被赋值。排查时可以按以下顺序检查:第一,确认字段是否定义在Sequence的Locals或Parameters中,而不是只写在Report模板里;第二,确认Pre-UUT回调是否真正执行并赋值成功;第三,确认Database步骤的字段映射是否引用了正确的PropertyObject路径;第四,确认Result记录中是否包含该字段的副本。
判断追溯链是否完整,最直接的方法是随机抽取一条Result记录,检查它是否同时具备产品层、设备层、人员层三类字段。如果缺少任何一层,就说明该层级的PropertyObject没有被正确挂接。这个检查可以做成自动化脚本,在每次测试结束后对Result进行校验,从而在产线端提前发现追溯断链,而不是等到质量分析时才发现数据不可用。
总结来说,Sequence负责组织,Step负责执行,Result负责记录,Report负责呈现,PropertyObject负责承载。追溯字段必须落在PropertyObject上,并在Result阶段固化,才能保证从单件测试到质量系统的完整数据链路。