3. 测试数据采集机制
TestStand 的数据采集不是“测试结束后把结果写进数据库”这么简单。它实际上是一条从 Step 执行到结果落库的完整数据链:Step 在运行时产生状态与测量值,Sequence 通过结果容器收集这些数据,附加数据补充上下文,实时数据流则决定哪些数据在测试过程中就被推送出去。理解这条链的每一段,才能设计出可追溯、可查询、可复现的质量数据体系。
Step 结果记录:状态与结果列表
每个 Step 执行后,TestStand 会在结果列表中生成一条记录,核心字段包括 StepName、Status、Error.Code、Error.Msg、StartTime、EndTime、TotalTime 以及 NumericLimit、StringValue、PassFail 等测量相关属性。状态取值通常为 Passed、Failed、Done、Skipped、Terminated、Error。其中 Done 表示执行完成但未做判定,Passed/Failed 才代表判定结果。
结果记录默认写入 RunState.Root.ResultList,可通过 RunState.Root.ResultList[0].TS.SequenceCall.ResultList 逐层访问。若在 Sequence 属性中勾选“Record Results”,则每个 Step 的结果都会进入结果列表;若关闭,则只保留顶层 Sequence 的结果。实际项目中建议对关键测量 Step 开启记录,对纯控制类 Step(如延时、消息弹窗)关闭,以减少数据量。
自定义结果与测量值
当 Step 的默认结果字段不足以表达业务含义时,需要写入自定义结果。常用方式有两种:一是通过 Step.Result 下的自定义属性,例如在 Numeric Limit Test 中增加 Step.Result.MyResult.MeasuredValue;二是通过 RunState.Root.ResultList[0].TS.SequenceCall.ResultList 追加自定义结果对象。
测量值写入时要注意数据类型与单位。例如电压测量应写入 Step.Result.Numeric = 3.301,同时把单位写入 Step.Result.Units = "V",把判定上下限写入 Step.Result.Limits.High = 3.4、Step.Result.Limits.Low = 3.2。这样在报表和数据库中才能还原“测了什么、值是多少、判定依据是什么”。
// 示例:在 Numeric Limit Test 的 Post-Expression 中写入自定义测量值
Step.Result.Numeric = Locals.MeasuredVoltage;
Step.Result.Units = "V";
Step.Result.Limits.Low = 3.2;
Step.Result.Limits.High = 3.4;
Step.Result.MyResult.Channel = "AI0";
Step.Result.MyResult.SampleRate = 10000;
自定义结果建议遵循“业务字段 + 原始值 + 单位 + 通道/条件”的结构。例如 MyResult.Channel 记录物理通道,MyResult.SampleRate 记录采样率,MyResult.Temperature 记录环境温度。这样后续做质量分析时,可以按通道、温度、批次等维度筛选。
附加数据:让结果带上上下文
附加数据(Additional Data)用于记录与测试结果相关但不属于 Step 判定本身的上下文信息,例如产品序列号、工位号、操作员、测试程序版本、夹具编号、环境温湿度、校准有效期等。TestStand 提供 RunState.Root.AdditionalData 容器,可在 ProcessSetup 或 SequenceFileLoad 中写入。
// 示例:在 ProcessSetup 中写入附加数据
RunState.Root.AdditionalData.ProductSN = "SN20240521-001";
RunState.Root.AdditionalData.StationID = "ST-03";
RunState.Root.AdditionalData.Operator = "zhangsan";
RunState.Root.AdditionalData.TestProgramVersion = "1.2.3";
RunState.Root.AdditionalData.FixtureID = "FX-07";
RunState.Root.AdditionalData.CalibrationDue = "2024-12-31";
附加数据与结果记录的关系是“一对多”:一次测试运行对应一组附加数据,而结果列表中有多条 Step 结果。写入数据库时,通常把附加数据放在主表,把 Step 结果放在明细表,通过 RunID 或 BatchID 关联。这样既避免重复存储,又便于按批次追溯。
实时数据流配置
实时数据流解决的是“测试过程中就要看到数据”的需求,例如产线看板、SPC 实时监控、异常报警。TestStand 本身不直接提供消息队列,但可以通过以下方式实现:在 Step 的 Post-Expression 中调用数据库存储过程、写入共享变量、调用 DLL 或使用 TestStand 的 RunState 事件回调。
常见配置方式是在 SequenceFilePostStep 回调中判断当前 Step 是否属于需要实时上报的类型,然后调用外部接口。例如:
// 示例:在 SequenceFilePostStep 回调中推送实时数据
if (Step.Result.Numeric != 0) {
Locals.Payload = "{"
+ "\"SN\":\"" + RunState.Root.AdditionalData.ProductSN + "\","
+ "\"Step\":\"" + Step.Name + "\","
+ "\"Value\":" + Step.Result.Numeric + ","
+ "\"Unit\":\"" + Step.Result.Units + "\","
+ "\"Status\":\"" + Step.Result.Status + "\""
+ "}";
// 调用 HTTP 或 MQTT 接口推送 Locals.Payload
}
实时数据流的关键参数包括:推送频率(每个 Step 推送还是按时间间隔批量推送)、失败重试策略、断线缓存、数据格式(JSON/CSV/二进制)。若产线网络不稳定,建议在本地先写入 SQLite 或文本缓存,网络恢复后再补传,避免数据丢失。
数据链整体关系
把上述四部分串起来看:Step 执行产生结果记录,结果记录中可包含自定义测量值;附加数据提供运行级上下文;实时数据流在测试过程中把关键结果推送到外部系统。四者共同构成 TestStand 的数据采集机制。下图展示了这条数据链的流向与落点。
配置要点与常见问题
第一,结果记录开关要按 Step 类型区分。测量类 Step 开启记录,控制类 Step 关闭,避免结果列表膨胀。第二,自定义结果字段命名要统一,建议在项目模板中预定义 MyResult 子属性结构,避免各工程师随意命名。第三,附加数据应在 ProcessSetup 中一次性写入,不要在多个 Step 中重复赋值。第四,实时数据流要设置超时与重试,避免因外部接口阻塞导致测试卡死。第五,数据库写入建议使用事务,先写主表再写明细表,失败时回滚,保证数据一致性。
总结来说,Step 结果记录解决“测了什么、结果如何”,自定义结果解决“业务字段如何表达”,附加数据解决“这次测试的上下文是什么”,实时数据流解决“数据何时到达外部系统”。四者配置得当,才能让 TestStand 的数据真正服务于质量追溯与产线决策。