4. 测试结果记录机制与日志配置

在 TestStand 中,测试结果记录并不是“测试跑完顺手写一行日志”这么简单。它是一条从执行引擎到数据库表的完整数据通路:Sequence 执行时产生 Step 结果,TestStand 引擎按配置决定哪些结果需要落库,再由 Database Logging 步骤把结果集写入目标表。理解这条通路,才能正确配置记录条件与日志级别,避免“该记的没记、不该记的写满库”这类常见问题。

结果记录流程:从 Step 结果到数据库行

TestStand 的结果记录机制可以拆成四个环节。第一,执行引擎在每个 Step 执行后生成一个 Result 对象,包含 Step 名称、状态(Pass/Fail/Done/Error)、测量值、单位、上下限、时间戳等属性。第二,Sequence 结束时(或按配置在每个 Step 后)引擎汇总本次执行的 ResultList。第三,Database Logging 步骤读取 ResultList,按“记录条件”筛选出需要写入的记录。第四,通过数据库连接把筛选后的记录插入目标表,并返回插入行数或错误码。

这里有一个关键点:结果记录发生在 Sequence 的清理阶段,而不是 Step 执行瞬间。这意味着如果 Sequence 中途被强制终止,未完成的 ResultList 可能不会写入数据库。因此对于关键测试,建议在 Sequence 的 Cleanup 中显式调用 Database Logging,而不是依赖自动记录。

TestStand 结果记录数据通路 ① Step 执行 生成 Result 对象 状态 / 测量值 / 上下限 时间戳 / 单位 ② ResultList 汇总 Sequence 级结果集 含所有 Step 结果 按执行顺序排列 ③ 记录条件筛选 按状态 / 级别过滤 决定哪些记录入库 减少无效数据量 ④ 写入数据库 INSERT 目标表 返回行数 / 错误码 事务提交 Database Logging 步骤关键配置项 Database 选择目标数据库连接 如 LocalDB / SQL Server 需提前配置 DSN 或连接串 Table 目标表名与字段映射 字段需与 Result 属性对应 支持自定义列表达式 Record Condition 记录条件表达式 如 Status == "Fail" 控制哪些结果入库 Log Level 日志级别设置 None / Fail / All 与条件配合使用

Database Logging 步骤配置要点

在 Sequence 中插入 Database Logging 步骤后,需要依次配置四个核心项。

数据库连接:在 Database 选项卡中选择已配置的数据库连接。TestStand 支持 ADO、ODBC 等连接方式。以 SQL Server LocalDB 为例,连接字符串可写为 Provider=SQLNCLI11;Server=(localdb)\MSSQLLocalDB;Database=TestResults;Trusted_Connection=yes;。建议在 Database Options 中勾选“Use Connection String”,避免依赖系统 DSN 导致部署环境不一致。

目标表与字段映射:在 Table 选项卡中指定表名,并把 Result 属性映射到表字段。例如目标表 dbo.TestLog 包含字段 StepName、Status、Measurement、LowLimit、HighLimit、Units、TestTime。映射时可用表达式引用当前结果,如 Step.Result.Measurement、Step.Result.Status。若字段类型为 datetime,需确保表达式返回合法时间格式。

记录条件(Record Condition):这是控制数据量的关键。默认条件下所有结果都会写入,对于包含数百个 Step 的产线测试,数据库会迅速膨胀。常见做法是只记录 Fail 或 Error 的结果,表达式写为 Step.Result.Status == "Fail" || Step.Result.Status == "Error"。若需要保留关键测量值用于趋势分析,可改为 Step.Result.Status != "Done" || Step.Result.Measurement != 0,即跳过无测量的 Done 步骤。

日志级别(Log Level):TestStand 提供 None、Fail、All 等预设级别。None 表示不记录;Fail 表示仅记录失败结果;All 表示记录全部结果。日志级别与记录条件的关系是:级别先做粗筛,条件再做细筛。例如级别设为 Fail,条件写 Step.Result.Status == "Fail",两者叠加后只写入失败记录。若级别设为 All 但条件写 Status == "Pass",则只写入通过记录,适合做通过率统计。

建议在开发阶段把日志级别设为 All,便于观察完整结果集;部署到产线后改为 Fail 或按条件过滤,避免数据库写入成为测试节拍的瓶颈。

记录条件与日志级别的配合策略

实际项目中,记录条件与日志级别需要根据追溯目标来组合。下面给出三种典型场景的配置示例。

追溯目标 日志级别 记录条件表达式 效果
只追溯失败原因 Fail Step.Result.Status == "Fail" 仅失败 Step 入库,数据量最小
失败 + 关键测量值 All Status == "Fail" || Step.Name == "MeasureVoltage" 失败记录与指定测量步骤都保留
全量追溯(研发阶段) All True 所有 Step 结果写入,便于分析

需要特别注意的是,记录条件表达式在每次 Database Logging 步骤执行时求值。如果表达式引用了不存在的属性(例如某个 Step 没有 Measurement 字段),TestStand 会报运行时错误。稳妥的做法是在表达式前加属性存在性判断,或使用 Step.Result.Measurement 前先确认该 Step 类型支持测量值。

实操示例:为电压测试配置结果记录

假设有一个电压测试 Sequence,包含三个 Step:PowerOn(无测量)、MeasureVoltage(测量值 3.3V,上下限 3.2~3.4V)、PowerOff(无测量)。目标是在产线只记录失败结果,同时保留 MeasureVoltage 的测量值用于趋势分析。

配置过程如下。第一步,在 Sequence 的 Cleanup 中插入 Database Logging 步骤,命名为 LogResults。第二步,Database 选择 TestResults 连接。第三步,Table 选择 dbo.TestLog,字段映射为:StepName = Step.Name、Status = Step.Result.Status、Measurement = Step.Result.Measurement、LowLimit = Step.Result.LowLimit、HighLimit = Step.Result.HighLimit、TestTime = Step.Result.StartTime。第四步,日志级别设为 All,记录条件写为:

Step.Result.Status == "Fail" || Step.Name == "MeasureVoltage"

这样配置后,如果 MeasureVoltage 测得 3.35V(Pass),该记录仍会入库,因为 Step 名称匹配;如果 PowerOn 或 PowerOff 执行成功,则不会写入。若 MeasureVoltage 测得 3.5V(Fail),也会写入,且 Status 字段为 Fail。通过查询 SELECT * FROM dbo.TestLog WHERE StepName='MeasureVoltage',即可得到所有电压测量记录,用于绘制趋势图或计算 Cpk。

记录条件中引用 Step.Result.Measurement 时,若当前 Step 没有该属性,表达式会报错。建议在条件中先判断 Step 类型,或把 Database Logging 放在只处理特定 Step 的子 Sequence 中。

结果记录中的常见问题与判断依据

配置完成后,如何判断记录是否按预期工作?最直接的方法是查看 Database Logging 步骤的返回结果。该步骤执行后会生成 Step.Result.NumRecordsInserted 属性,表示实际插入的行数。如果该值为 0,说明记录条件把所有结果都过滤掉了,需要检查条件表达式是否过严。如果该值为负数或步骤状态为 Error,则说明数据库连接或字段映射有问题,应查看 Step.Result.Error.Code 和 Step.Result.Error.Msg。

另一个常见问题是重复记录。如果 Sequence 被多次调用,而 Database Logging 放在每次都会执行的 Cleanup 中,就会产生重复行。解决办法是在记录条件中加入执行 ID 或批次号判断,或者把 Database Logging 移到只在主 Sequence 中执行一次的位置。对于需要严格去重的场景,可以在目标表上建立唯一索引,并在插入时使用 IF NOT EXISTS 逻辑。

最后,日志级别与记录条件的组合需要在实际环境中验证。建议先用小批量测试数据跑一遍,检查 NumRecordsInserted 是否符合预期,再逐步放大到全量测试。只有确认记录条件、字段映射和数据库连接三者都正确,结果追溯链条才算真正建立起来。