本文讨论了设计和开发TestStand用户界面应用程序的最佳实践:
TestStand使用模块化架构设计,利用具有单一用途的独立组件,使得整个系统的开发和维护更加简单直接。
用户界面是模块化TestStand架构中一个独立组件
用户界面组件为开发人员和测试操作员提供了相应机制,用于在测试系统中创建和运行序列。在模块化架构中,用户界面(UI)和底层TestStand应用程序之间应存在清晰的界限。这种架构具有以下优点:
TestStand用户界面与TestStand引擎API通信以执行其各种功能,例如获取测试执行的状态、创建和编辑序列以及配置设置。TestStand还提供了一组用户界面控件和单独的UI API,让您可以快速创建自己的TestStand用户界面。
TestStand用户界面(UI)控件是一组ActiveX控件,这些控件实现了应用程序显示、执行和调试测试序列所需的常用功能。这些ActiveX控件显著减少了用户界面与TestStand API交互以处理用户界面任务所需的源代码数量。使用“属性(Properties)”页面或调用可用的属性和方法,可配置这些控件。有关如何在LabVIEW、CVI、C#或VB.NET中使用TestStand UI控件的更多信息,请参见TestStand UI控件帮助主题。
TestStand UI控件提供了两组用户界面控件:管理器控件和可见控件。
管理器控件调用TestStand API来执行各种任务,例如加载文件,启动执行以及检索顺序和执行信息。当发生应用程序事件时(例如当用户登录时、执行到达断点时,或者用户更改他们正在查看的文件或顺序时),管理器控件也会通知您。管理器控件在运行时不可见。
可见控件向用户显示信息,例如显示当前执行状态的执行视图控件。可见控件还允许用户与UI交互,例如使用按钮控件执行测试。 可见控件必须连接到管理器控件,从而确定其运作方式。 这种连接通过使用管理器控件的连接方法来实现。连接控件时,管理器控件会自动处理用于管理可见控件行为的内部逻辑。 您可以建立视图连接、列表连接、命令连接和信息源连接,具体取决于所连接的管理器控件和可见控件的类型以及可见控件的期望行为。
将可视TestStand UI控件连接到管理器控件以定义其行为。
有关在各种编程环境中使用TestStand UI控件的更多详细信息,请参阅TestStand用户界面控件帮助主题。 您还可以使用连接UI控件演示来查看可创建的可用连接的行为。
此外,您还可以将编程环境中本地提供的控件与TestStand UI控件结合使用。使用本地控件时,可以使用用户界面API直接与管理器控件进行通信,从而实现与TestStand相关的功能。有关编写直接调用TestStand API的应用程序的更多信息,请参考使用原生控件构建TestStand UI的示例。
TestStand提供了几个示例和组件,可用于帮助构建用户界面。参考用户界面示例,有利于开始开发自定义用户界面。TestStand还附带了多种用户界面组件,这些组件能够实现在这些用户界面应用程序中使用的常见功能,您可以在自己的应用程序中复用这些用户界面。
TestStand附带了使用支持编程语言的简化和全功能用户界面应用程序示例,此类编程语言包括LabVIEW、Labwindows™/CVI™、C#和VB.net。TestStand提供了以每种受支持编程语言编写的示例源代码。您可以参考此源代码,以便开始开发自定义用户界面,也可以按原样使用它们。
简化用户界面最大程度地减少了显示内容,不包含菜单栏,其目的是供测试操作员在已部署的测试系统上作为用户界面使用。而全功能用户界面则显示了更多信息,添加了菜单栏,并提供了调试功能。 全功能用户界面还具备编辑器模式,可用于创建和修改测试序列,例如TestStand序列编辑器。
在学习如何使用TestStand UI控件进行开发时,简化用户界面示例是一个很好的起点。 对于LabVIEW、LabWindows/CVI或C#实现,可以使用下方的指南查看源代码及其工作方式的详细说明:
在为测试系统开发用户界面时,务必要考虑将与应用程序进行交互的所有用户的目标和需求。 测试系统用户通常可以分为以下几类角色:
在为测试系统用户规划和设计适当的用户界面时,您扮演的是框架开发人员的角色。 借助TestStand UI控件,您可以根据用户的需求完全自定义用户界面。例如,测试操作员可能只需要启动测试并查看结果。 但测试开发人员则需要完全的访问权限来创建和编辑序列文件。
您可以为测试开发人员提供全功能用户界面,该界面允许创建和编辑序列文件,例如TestStand提供的全功能UI示例或序列编辑器。 对于测试操作员,可以设计一个简化用户界面,其中仅显示一个用于开始测试的按钮以及一个显示测试结果的显示控件,从而确保操作员可以成功运行测试。 向操作员提供较复杂的UI可能会导致出现问题,因为这需要操作员事先接受其他培训,且由于可用功能过多,操作时更容易出错。
通过使用TestStand UI控件来开发UI,您将能够从全功能UI无缝迁移到简化UI。这两种UI均基于TestStand引擎、序列、过程模型和其他组件而构建,并且会共用这些组件。
全功能UI(例如序列编辑器)和简化操作员UI可以利用相同的测试代码无缝交互
除了创建单独的用户界面,还可以使用TestStand用户管理来自定义在单个用户界面应用程序中提供的功能。 在不同角色执行相同测试的情况下,这种方法更适用。 例如,负责分析失败测试故障的技术人员将需要访问诊断数据,如执行和/或测试报告的视图,而这些数据通常不会向操作员显示。 为技术人员提供单独的UI应用程序会出现问题,因为他们无法从单独的应用程序访问当前的执行信息。 要解决这个问题,可以创建一个单独的用户界面,为更高级用户提供更多视图。 例如,可以使用ctrl + shift + alt + insert将TestStand全功能用户界面更改为编辑器模式,让高级用户获得更改序列的权限。
全功能UI示例可以在操作员模式或编辑器模式下执行
为TestStand用户管理器定义用户时,TestStand UI控件会根据当前用户的权限自动启用或禁用其状态。使用Engine.CurrentUserHasPrivilege TestStand API方法,可根据用户的权限定义自定义行为,例如隐藏或显示用户界面的某些部分。有关定义用户和权限的更多信息,请参阅管理用户帮助主题。
在开发TestStand用户界面时,务必明确区分在UI中实现的功能以及在测试系统其他组件中实现的功能。 本节概述了常见的测试系统功能以及在TestStand架构中实现这些功能的情况。
在许多情况下,测试系统需要在测试开始执行之前执行操作。例如,您可能需要初始化测试硬件并验证硬件是否已校准,或者检查用户权限以初始化用户界面。
要处理这些功能,可以在前端回调序列文件中使用LoginLogout序列。 此序列默认在TestStand启动时由TestStand UI应用程序管理器控件执行,并且默认向用户显示登录对话框。 向此序列添加功能具有以下好处:
除了LoginLogout序列之外,还可以在前端回调中定义其他序列,以便在其他情况下实现调用的功能。 对于这些其他序列,需要使用Engine.CallFrontEndCallbackEx()方法将代码添加到用户界面,以便在需要时调用序列。 使用这个方法,无需管理对序列文件的引用,因为TestStand会自动加载和卸载前端回调,所以非常方便。
测试系统通常使用与测试一起工作的独立工具或应用程序。 例如,可以启动数据库配置实用程序或分析应用程序。 您无需将这些功能构建为用户界面应用程序的模块,而是可以通过植入独立工具来模块化系统,并通过自定义工具菜单项提供对相应的访问。 通过“工具(Tools)”»“自定义(Customize)”菜单,可从序列编辑器自定义工具菜单。在自定义对话框中,可以添加新的工具菜单项并配置其行为。
创建自定义工具,向实现工具菜单的任何用户界面提供更多功能
所做的更改将保存到单独的配置文件中,因此所有用户界面都将显示您创建的自定义条目。 如需更多信息,请参考自定义工具菜单对话框帮助主题。
用户界面需要为用户提供一种开始执行序列的方法,但重要的是,UI不能直接与任何序列文件耦合。 要允许用户开始测试,可以创建一个按钮来调用当前已加载序列的执行入口点,包括直接运行序列或使用过程模型入口点(例如 Single Pass 和 Test UUTs)。 用户界面不应包含序列执行之前或之后执行的功能,此功能应通过过程模型实现。
过程模型还可以定义配置入口点,用户可以使用这些入口点配置过程模型设置。确保任何模型设置都是从这些入口点配置,而不是直接通过用户界面配置。通过将功能构建到过程模型中,这些功能可在任何TestStand用户界面应用程序和序列编辑器中使用。
有关使用过程模型的更多信息,请参阅TestStand过程模型定制的最佳实践文档。
尽管将用户界面与测试系统的其他组件(例如测试序列文件和过程模型)分离开很重要,但用户界面必须与这些组件有效通信。 本节介绍了可用于在这些组件之间进行通信且同时仍保持这种模块化的方法。
在执行测试时,测试系统必须向操作员提供反馈,表明执行的当前状态,例如正在运行的测试或当前的测试结果。通常,可以使用TestStand UI控件来显示此信息,例如执行视图和报告视图。通过连接到管理器控件,这些控件将随时更新以显示由引擎管理的当前执行状态。
在某些情况下,可能需要显示有关测试的更多具体信息。 执行序列或代码模块必须将此信息传递到用户界面进行显示,或指示用户界面采取措施。为了在不引入耦合的情况下传达此信息,可以使用UI消息来实现通信。使用序列文件属性或UI变量作为通信方式的替代方法,在序列文件和用户界面之间创建了不必要的依赖关系。例如,从序列更新全局文件,然后在用户界面中检查其状态,这样会在全局文件和UI之间引入耦合。 首选UI消息有两个原因:
有关使用UI消息的更多信息,请参阅“使用TestStand用户界面消息(UI消息)”
UI消息包含了表明消息用途的消息ID。 TestStand定义了多个UI消息ID,这些ID定义了由引擎自动发送或由TestStand用户界面控件自动处理的消息。 例如,消息ID UIMsg_EndExecution(值4)在执行结束后由引擎发送。 管理器控件将许多这些UI消息显示为单独的事件;在这种情况下,您可以定义处理ApplicationManager EndExecution事件的处理程序,而不是直接使用UI消息事件处理程序。
其他UI消息由默认过程模型发布,例如UIMsg_ModelState_Identified(值:32),过程模型会在识别UUT的序列号之后发布此消息。 此外,您可以使用Thread.PostUIMessageEx TestStand API方法从代码模块、测试序列或过程模型中发布预定义或自定义的UI消息。
UIMessageCodes帮助主题中提供了UI消息ID或事件代码的列表。
您可以自行定义用于自定义操作(例如更新图表和直方图中的数据)的UIMessage。定义自定义UIMessage时,请从UIMsg_UserMessageBase事件代码开始指定唯一的事件代码。发布自定义UIMessage时,传递已定义的事件代码和要显示的数据。UI消息提供了用于数值、字符串或ActiveX数据的数据字段,可以在调用postUIMessageEx方法时指定这些字段。在定义处理程序以响应用户界面中的UI消息时,此数据会作为参数在事件回调中显示。
要定义用户界面如何处理UI消息,请为以下两个程序管理器事件中的其中一个添加事件回调,从而将操作员界面配置为在处理UI消息时运行用户定义的代码:
有关为用户界面定义事件处理程序的信息,请参阅TestStand帮助中的处理事件主题。
在某些情况下,需要将信息从用户界面传达到测试序列。 但是,序列和UI之间的通信应始终由序列发起,从而确保序列处于可修改其数据的状态。 为此,该序列可以发布带有自定义代码的UI消息,以此表明它已准备好进行通信。发布UIMessage时,将同步参数设置为“True”,以便等到用户界面处理该消息后再执行。用户界面处理UIMessage时,它会检索SequenceContext对象并写入或读取某些变量,例如过程模型局部变量。
在许多情况下,UI并不是用户指定测试相关数据的最佳位置。 例如,如果数据与过程模型中的任务有关,最好修改或创建配置入口点,以便从默认菜单访问该入口点。
有关演示发布和处理UI消息(包括使用UI消息从用户界面收集数据)的示例,请参阅处理UI消息随附示例