2、TestStand基础架构:理解TestStand的序列、步骤、数据类型、执行模型以及默认用户界面(UI)的组成

TestStand作为NI推出的测试执行管理平台,其核心价值在于将测试流程的执行逻辑与具体测试代码分离。在开始定制用户界面之前,我们必须先理解TestStand在后台是如何组织测试流程的。如果把TestStand比作一个操作系统,那么序列(Sequence)就是进程,步骤(Step)就是线程指令,数据类型就是内存中的变量结构,而执行模型则是CPU的调度策略。本章将深入剖析这四大核心支柱,并拆解默认用户界面的构成,为后续的UI定制打下坚实的架构基础。

TestStand 核心架构关系图 序列文件 (.seq) 包含:序列集合、数据类型定义、变量、文件全局配置 主序列 (MainSequence) 子序列 (SubSequence) 清理序列 (Cleanup) 步骤 (Step) — 执行单元 测试步骤 调用步骤 流程控制 加载/存储 消息/提示 属性:名称 | 类型 | 步骤属性(Step Properties) | 适配器(Adapter) | 加载选项(Load Options) 执行控制:启用/禁用 | 跳转(Pass/Fail/Done) | 循环 | 超时 数据类型与变量 Number String Boolean 容器:Array / Container / Custom Data Type 执行模型 (Execution Model) 入口点 → 预测试(Pre) → 测试循环(For/While) → 后测试(Post) → 清理(Cleanup) 多线程执行:并行测试 / 批量测试 默认用户界面 (UI) 组成 执行控制面板 报告查看器 变量监视器 序列查看器 调试工具栏

上图清晰地展示了TestStand各核心组件之间的逻辑关系:序列文件是容器,步骤是执行的最小单元,数据类型为数据交换提供规范,执行模型定义了运行时的调度逻辑,而默认UI则是与操作员交互的窗口。下面我们逐一深入解析。

2.1 序列与步骤:流程的组织与执行单元

核心原理:序列的层次化结构

在TestStand中,一个序列文件(.seq)是测试程序的完整载体。它内部可以包含多个序列(Sequence),每个序列又由若干步骤(Step)按顺序排列组成。TestStand强制要求每个序列文件必须包含一个名为MainSequence的主序列,它是执行入口。此外,开发者可以创建任意数量的子序列(SubSequence)和清理序列(Cleanup)。

步骤是TestStand中最基本的执行单元。每个步骤都有一个步骤类型(Step Type),决定了该步骤的行为。常见的步骤类型包括:

  • 测试(Test):调用外部代码模块(如DLL、VI、C/C++函数)执行具体的测量或计算,并返回布尔型结果(Pass/Fail)。
  • 调用(Call):调用另一个序列(子序列),实现代码复用。
  • 流程控制(Flow Control):包括If/Else、For循环、While循环、Jump跳转等,控制执行路径。
  • 加载/存储(Load/Store):用于加载或保存文件、数据库记录等。
  • 消息(Message):弹出对话框或向操作员显示提示信息。

操作流程:创建与配置步骤

  1. 在序列编辑器中,右键点击步骤列表空白处,选择Insert Step。
  2. 从步骤类型列表中选择所需的类型(如Test、Call、If等)。
  3. 在步骤属性(Step Properties)对话框中配置参数。对于Test步骤,需要指定模块(Module)(即调用的DLL或VI)、适配器(Adapter)(如LabVIEW Adapter、C/C++ Adapter)以及输入输出参数。
  4. 设置步骤的执行控制属性,例如Step Enabled(是否启用)、Jump on Pass/Fail(根据结果跳转到指定步骤)、Loop(循环次数)等。
经验提醒:在定制UI时,步骤的Step Name和Step Description属性会直接显示在UI的步骤列表中。务必使用有意义的命名规范(如“测量电压_通道1”),而不是默认的“Step 1”。这能极大提升操作员在UI上定位问题的效率。

案例拆解:一个典型的测试序列结构

假设我们要开发一个电源模块的测试程序,其序列结构如下:

序列名步骤名步骤类型功能描述
MainSequence初始化仪器Call调用子序列,初始化DMM和电源
测试电压精度Test调用DLL函数测量电压并判断是否在规格内
测试纹波Test调用示波器测量纹波
Cleanup关闭仪器Call调用子序列,关闭所有仪器连接

在这个结构中,MainSequence负责顶层调度,Cleanup序列保证无论测试是否通过,仪器都能被安全释放。这种层次化设计使得流程清晰,且便于在UI中通过树形控件展示。

常见误区:初学者常将所有步骤都塞进MainSequence,导致序列冗长且难以维护。正确的做法是将可复用的功能(如仪器初始化、数据记录)封装为子序列,通过Call步骤调用。这不仅减少了重复代码,也让UI上的执行流程显示更加简洁。

2.2 数据类型与变量:数据交换的基石

核心原理:TestStand的类型系统

TestStand内置了一套丰富的数据类型系统,用于在步骤之间、序列之间以及UI与执行引擎之间传递数据。主要数据类型包括:

  • 基础类型:Number(浮点/整数)、String、Boolean、Path(文件路径)。
  • 容器类型:Array(数组)、Container(类似C语言的结构体或Python的字典)。
  • 自定义类型(Custom Data Type):用户可以将多个基础类型和容器组合成一个新的类型,例如定义一个MeasurementResult类型,包含Value(Double)、Unit(String)、Status(Boolean)等成员。

变量在TestStand中有明确的作用域:文件全局(File Global)、序列(Sequence Local)和步骤(Step Local)。理解作用域对于UI开发至关重要,因为UI控件通常需要绑定到特定作用域的变量上。

判断方法:如何选择合适的数据类型

当需要从测试步骤向UI传递多个相关结果时,强烈建议使用自定义容器类型。例如,定义一个TestResult容器,包含TestName、MeasuredValue、UpperLimit、LowerLimit、PassFail。这样,UI上的表格控件可以直接将这个容器数组绑定为数据源,无需逐个变量映射。

// 在TestStand中定义自定义类型的示例(伪代码)
CustomType: PowerSupplyTestResult
  Members:
    - TestName: String
    - Voltage: Number
    - Current: Number
    - Efficiency: Number
    - PassFail: Boolean

实战场景:变量在UI中的绑定

在默认的TestStand UI中,变量监视器(Variables)面板允许操作员实时查看和修改变量值。在定制UI时,我们通常会在测试开始前将操作员输入的参数(如批次号、操作员ID)写入到File Global变量中,然后在测试步骤中读取这些变量。例如,在UI的登录界面,操作员输入工号后,我们通过TestStand API将值赋给FileGlobal.OperatorID,后续的报告生成步骤即可引用该变量。

关键点:UI与TestStand引擎的数据交互是通过属性加载器(Property Loader)或Engine API完成的。在定制UI时,你需要明确知道变量所在的上下文(Context)(是序列上下文还是文件上下文),才能正确读写。

2.3 执行模型:理解TestStand的运行时调度

核心原理:执行模型的结构

TestStand的执行模型定义了当一个执行(Execution)被启动后,序列如何被调度执行。默认的执行模型包含以下几个阶段:

  1. 入口点(Entry Point):即MainSequence的第一条步骤。
  2. 预测试(Pre):通常用于初始化硬件、建立连接。
  3. 测试循环(Test Loop):这是核心部分,通常是一个For循环或While循环,用于遍历测试项目或重复执行测试。
  4. 后测试(Post):用于数据处理、生成报告。
  5. 清理(Cleanup):无论前面的步骤是否失败,此阶段都会执行,用于释放资源。

这个模型是TestStand的默认执行模型,开发者可以在序列属性中修改或完全自定义。理解这个模型对于UI开发非常重要,因为UI上的进度条和状态指示通常需要监听当前执行到了哪个阶段。

操作流程:监控执行状态

在定制UI时,我们通过TestStand的Execution对象来监控状态。主要的事件包括:

  • OnExecutionStarted:执行开始时触发。
  • OnStepStarted:每一步开始前触发。
  • OnStepPassed / OnStepFailed:步骤结束时触发。
  • OnExecutionEnded:执行结束时触发。

利用这些事件,UI可以实时更新当前步骤名称、测试结果、剩余时间等信息。

案例拆解:多线程并行执行

TestStand支持多线程执行,即同时运行多个Execution。例如,在测试双通道电源时,我们可以创建两个执行,分别测试通道1和通道2。在UI上,我们需要为每个执行创建一个独立的执行视图(Execution View),显示各自的进度和结果。默认UI中的执行管理器(Execution Manager)就是为此设计的。

执行ID状态当前步骤结果
1Running测试电压精度Pending
2Running测试纹波Pending
风险提示:多线程执行虽然提高了效率,但也引入了资源竞争问题。例如,两个执行同时访问同一个仪器句柄会导致冲突。在定制UI时,如果允许操作员启动多个执行,必须在UI层面明确提示当前并发的执行数量,并在测试代码中使用锁(Lock)机制保护共享资源。

2.4 默认用户界面(UI)的组成与设计逻辑

核心原理:默认UI的模块化设计

TestStand安装后自带的默认UI(通常基于LabVIEW或C#开发)是一个功能完整的参考实现。它的设计遵循了模块化原则,主要包含以下几个核心区域:

  • 执行控制工具栏(Execution Control Toolbar):包含运行、暂停、停止、单步执行等按钮。
  • 序列查看器(Sequence Viewer):以树形或列表形式显示当前加载的序列文件中的步骤。
  • 变量监视器(Variables):显示当前执行上下文中的变量值,并允许操作员修改。
  • 报告查看器(Report Viewer):显示测试完成后生成的报告内容。
  • 状态栏(Status Bar):显示当前执行状态、错误信息等。

操作流程:启动与调试

当操作员点击运行按钮时,UI调用TestStand Engine API创建一个新的Execution,并指定入口序列。UI通过事件回调机制接收引擎的状态更新,并刷新界面上的控件。例如,当OnStepStarted事件触发时,UI会高亮当前正在执行的步骤。

实战场景:从默认UI到定制UI的过渡

默认UI虽然功能完整,但往往不符合特定产线的操作习惯。例如,默认UI的变量监视器暴露了太多技术细节,操作员可能会误修改关键参数。在定制UI时,我们通常会:

  1. 隐藏技术性面板:移除变量监视器或序列查看器,只保留执行按钮和状态显示。
  2. 定制报告视图:将报告查看器替换为更简洁的Pass/Fail统计界面。
  3. 添加工单输入界面:在测试开始前,强制操作员扫描条码,并将条码值写入TestStand变量。
总结复盘:理解TestStand的基础架构是UI定制的第一步。你需要清楚:序列和步骤是流程的骨架,数据类型是血肉,执行模型是神经系统,而UI则是外在表现。在后续章节中,我们将深入探讨如何通过TestStand API和事件机制,将这些底层能力封装成符合业务需求的定制界面。