TestStand 自定义步骤类型开发最佳实践【2】
概览
自定义步骤类型使用户可通过以下方式扩展现有步骤:
- 配置步骤属性的值,并确定步骤用户可以修改哪些属性
- 添加新的步骤属性来存储自定义数据,可以选择性地将这些数据记录到测试结果中
- 定义要在执行主模块之前或之后调用的代码
- 创建接口,使用户在编辑时可以配置自定义步骤属性
设计完善的步骤类型可以加快序列开发、减少调试工作、使开发人员能够共享标准化代码,并可以在多个测试站和独立组之间实现一致性。但是,自定义步骤类型可能需要大量时间来计划、编程、调试、部署和维护。
在阅读本文之前,请确保您熟悉创建自定义步骤类型的过程。关于此过程的详细信息,请参考《创建波形自定义步骤类型》教程。
内容
- 选择使用自定义步骤类型的时机
- 定义自定义步骤类型的要求
- 管理步骤类型数据
- 子步骤可用于配置自定义步骤类型功能
选择使用自定义步骤类型的时机
在开始设计自定义步骤类型之前,应考虑其他可能更适合新功能的方法。
在以下情况下,不建议创建或修改自定义步骤类型:
- 新功能会影响所有或许多类型的步骤。 在这种情况下,请考虑使用引擎回调,它将在每个步骤之前或之后执行。
- 希望提供现有步骤的基本配置,但是不需要新的功能或属性。 在这种情况下,请创建包含步骤更改的步骤模板。
- 希望提供可以在编辑时使用的工具或实用程序。 在这种情况下,请使用自定义工具菜单项来调用自定义代码。
可在以下情况下创建或修改步骤类型:
- 相应功能无法在内置步骤类型中实现。
- 相应功能需要修改在现有步骤类型实例中无法修改的属性,
- 相应功能要求必须在调用测试代码之前或之后执行操作,例如设置步骤或分析结果。
- 希望借助用户界面简化配置步骤的用户体验。
- 希望与其他组、公司或客户共享功能。
步骤模板与自定义步骤类型
在序列中开发和配置步骤,然后将这些步骤拖放到“插入选板”(Insertion Palette)的“模板列表”(Templates List)中,即可创建步骤模板。TestStand会将步骤实例的副本保存为模板,将步骤模板拖放到新序列中即可进行复用来快速创建新序列。
步骤模板和自定义步骤类型之间的区别在于,模板只能通过现有步骤类型来创建,并且模板仅包含与原始步骤类型相同的功能。相对于步骤模板,自定义步骤类型在修改或重新设计方面具有更大的灵活性。对于添加到“模板列表”(Templates List)的步骤,只能配置原始步骤类型的开发人员启用的设置。相比之下,新自定义步骤类型可用于创建具有全新行为的全新步骤。同样,对步骤模板的更改仅影响该步骤未来的实例,而不会更改该步骤的现有实例。
使用步骤模板有一个好处,若要以相同的方式复用同一步骤,可以避免多次自定义步骤设置。例如,如果要将IVI电源设置为5 V,然后再设置为3.3 V,并计划在整个序列中多次执行此步骤,那么在最初使用并配置步骤后创建两个步骤模板可以节省时间。但是,如果需要在运行测试代码之前先配置电源的步骤,创建自定义步骤类型则是一种更好的方法。
步骤模板 |
自定义步骤类型 |
|
|
定义自定义步骤类型的要求
设计自定义步骤类型时,请考虑框架开发人员和测试开发人员各自的职责。 框架开发人员的职责是开发工具和构建块,而测试开发人员的职责是使用这些工具来实现实际的测试代码。
设计自定义步骤类型时,您需要履行框架开发人员的职责,请务必从最终用户和测试开发人员的角度审视所开发的步骤类型的功能。
确定自定义步骤类型的要求时,请遵循以下准则
- 定义自定义步骤类型的范围。 思考测试开发人员将使用自定义步骤类型执行哪些任务。 此范围应足够大,能够处理这些用例,但范围过大会使步骤类型的目的不明确。
- 根据步骤类型的范围,定义步骤类型需要的数据以及存储数据的方式。
- 定义步骤类型的所有实例应实现的所有功能。 确保在步骤属性中定义此功能所需的所有数据。
- 定义哪些数据可由用户编辑,哪些数据应记录到报表或数据库中。
- 思考将来可能会需要的功能或配置,并确保这些项目的实现方式可使步骤类型的更新顺利传递到所有实例。
管理步骤类型数据
自定义步骤类型将数据存储在多个属性和设置中,这些属性和设置可用于配置步骤类型实例的行为,以及管理步骤类型功能所需的数据。其中包括:
- 内置类型属性,存在于所有步骤类型中,无法在相应类型的实例中进行修改。
- 默认值属性,用于定义新步骤实例的状态,可在相应类型的实例中进行修改。
- 为步骤类型定义的自定义属性。
内置类型属性
内置步骤类型属性存在于所有步骤类型中,用户无法在相应步骤类型的实例中修改这些设置。 此外,对这些属性的值所做的更改都将传递到相应步骤类型的所有实例。
示例:所有步骤类型都定义了一个说明表达式,该表达式显示在步骤实例旁边的“步骤”(Steps)窗格中。 此属性存在于所有步骤类型中,但每种步骤类型的相应值均单独设置。 此值无法在步骤类型的实例中进行修改。
访问步骤类型的内置属性:
- 使用“查看”(View) »“类型”(Types)菜单或快捷键Ctrl + T导航到类型视图
- 右键单击步骤类型,然后选择“属性…”(Properties…),启动属性窗口
步骤类型属性对话框
此对话框中的大多数设置均为默认值,下一部分将介绍这些内容。 内置属性包括:
- 图标 — 步骤的图标,位于<TestStand Public>/Components/Icons文件夹中
- 步骤说明表达式 — 步骤说明,显示在步骤类型实例的步骤窗格中
- 版本设置 — 用于解决类型冲突
- 项目名称表达式(菜单选项卡)— 定义插入选板中步骤的名称
创建自文档化说明
由于相应说明无法在步骤实例中配置,因此您可以作为步骤类型开发人员对说明进行定义,从而帮助用户创建自文档化步骤。 说明字段由一个表达式指定,该表达式可用于创建显示重要步骤属性的动态说明。 当用户更改步骤类型实例中的这些属性值时,说明将更新,使用户可以快速浏览步骤状态,而无需导航至步骤设置窗格。
示例:下图第二步中的“步骤说明”更具有描述性,提供的文档更佳。 此说明使用以下表达式来定义说明:
"Calibrate Channels: " + Str(Step.minChannel) + " - " +Str(Step.maxChannel)
如果用户配置了minChannel和maxChannel步骤属性,则此表达式会将说明配置为动态更新。
步骤说明示例
步骤属性默认值
开发步骤类型时,可以为所有用户可配置步骤设置配置默认值。 此外,这些属性可配置为在步骤实例中禁用,从而使设置的默认值无法被修改。 与内置属性一样,默认值也在步骤属性窗口中进行定义。 但是,所有默认值设置都包含“默认”一词,它可能存在于设置名称中或配置默认值的设置选项卡中。
示例:状态表达式属性用于确定步骤结果。 此属性存在于所有步骤类型中,每种步骤类型均设置为默认值。 在某些步骤类型中,例如“数值边界测试”,状态表达式在步骤类型中被禁用,因此无法在单个数值边界测试步骤中对表达式进行编辑
设计自定义步骤类型时,可以禁用在步骤类型的实例之间不会变化的任意属性。 如此可以更好地控制步骤类型用户修改行为的方式。但是,限制用户编辑步骤设置可能会影响灵活性,因此您应仅禁用确定用户始终不需要修改的设置。
请记住,即使禁用在步骤实例中编辑步骤属性默认值的功能,以后对这些默认值所做的更改也不会传递到步骤类型的实例。关于如何解决此问题的更多信息,请查看《更新和维护步骤类型》。
更新默认值时的注意事项
不应使用这些属性的值来定义步骤类型开发人员可能需要更新的步骤类型功能。 例如,请勿使用步骤的“Post”表达式来实现步骤类型特定功能。 如果需要在步骤类型的未来版本中更新此功能,将无法确保步骤的所有实例都将更新。 而是应在步骤前或步骤后的子步骤中实现此功能。
自定义属性
除内置属性外,还可以定义特定于步骤类型的自定义属性。 这些属性可用于存储与步骤类型功能具体相关的数据。
示例:数值边界测试步骤包含一个“Limits.High”属性,这是数值边界步骤类型的独有属性。 该类型将此属性的默认值定义为11,用户可以修改其创建的每个实例中的该值。
创建自定义步骤属性:
- 使用“查看”(View) »“类型”(Types)菜单或快捷键Ctrl + T导航到类型视图
- 展开步骤类型项。
- 右键单击“父”(Parent)属性或“<Right click to insert field>”条目来添加新属性
如果在步骤类型的结果容器中定义了属性,则该属性将包含在结果集合中。 然后,IncludeInReport或IncludeInDatabase标志可用于将数据记录到报表或数据库中。
默认状态下,用户可以更改每个步骤实例的步骤属性值。 但是,如果在步骤类型中为步骤属性设置了共享标志,则该值将被锁定为步骤类型中的值。 与步骤默认值不同,对该值的更新将传递到步骤类型的实例。
确定自定义步骤类型的范围
为步骤属性选择的数据类型应由步骤类型的范围决定。例如,考虑数值边界测试和多数值边界测试步骤。 虽然多数值边界测试可以容纳更多边界并具有更多功能,但是也增加了编辑时用户界面和结果记录的复杂性。 更基本的数值边界测试的范围更小,界面也更简单。需要的开发工作更少,除此之外,对测试序列开发人员而言,范围更小的步骤也更易于使用。
在开发自己的自定义步骤类型时,请务必在定义自定义属性之前先定义步骤的范围,因为所选的属性会显著影响步骤类型的复杂性。
子步骤可用于配置自定义步骤类型功能
以下各部分说明了如何使用子步骤来实现以下步骤类型行为:
- Runtime功能,应在主代码模块之前或之后对步骤类型的所有实例执行
- 用户界面,在编辑测试序列时查看和编辑步骤数据
- 测试开发人员创建步骤的新实例时执行的功能
实现子步骤
子步骤使用所提供的TestStand适配器之一调用代码模块。 子步骤无法在步骤的实例中修改,对子步骤设置的所有更改都将传递到步骤类型的实例。
将子步骤添加到自定义步骤类型:
- 使用“查看”(View) »“类型”(Types)菜单或快捷键Ctrl + T导航到类型视图
- 右键单击步骤类型,然后选择“属性…”(Properties…)
- 选择“子步骤”(Substeps)选项卡。 选择与所需代码模块匹配的适配器
- 单击“添加”(Add),然后选择子步骤类型。 子步骤列表中将出现一个新条目
- 选择相应条目,然后单击“指定模块”(Specify Module),为子步骤配置代码模块,方法与为步骤配置代码模块相同
多数值边界测试步骤类型的步骤后和编辑子步骤
定义步骤类型的Runtime功能
步骤前和步骤后子步骤可用于为步骤类型定义Runtime功能。 在步骤执行时,这些子步骤会在主代码模块之前或之后执行。
示例:消息弹出步骤类型使用C代码模块在运行时创建和显示消息框。 此模块将在步骤后子步骤中调用,
步骤执行顺序:子步骤
这些子步骤可用于定义适用于步骤所有实例的功能。 通常,子步骤需要与步骤类型的行为相关的特定数据。 在自定义步骤属性中定义此数据,从而确保此数据在步骤的所有实例中均可用。
如果存在多个步骤前或步骤后子步骤,则它们将按照“步骤类型属性”(Step Type Property)对话框“子步骤”(Substep)选项卡上显示的顺序执行。
默认状态下,测试开发人员可以为步骤类型的每个实例指定一个代码模块。 如果步骤类型不需要代码模块,则应在“禁用属性”(Disable Properties)选项卡中为步骤类型配置禁用“指定模块”(Specify Module)选项。 许多内置步骤类型都采用这种设计方式,例如语句和消息弹出步骤。
提供长期操作的视觉反馈
TestStand会等待步骤前或步骤后子步骤中的代码执行,然后再继续下一步操作。如果这些步骤的代码模块运行缓慢或静默运行,TestStand看起来会像是无响应。为了解决此问题,可以更改光标或使用UI消息(例如UIMsg_ProgressPercent)来更新状态栏中的进度条。
关于如何使用此方法的更多信息,请查看《使用UI消息更新状态栏》
使用终止监视器
您开发的代码模块应包括并定期轮询终止监视器,以便在用户使用TestStand或TestStand API中的内置选项终止或中止序列执行时正常应对。 如果用户终止序列执行,借助终止监视器可以快速终止相应子步骤。
关于在代码中实现终止监视器的更多信息,请查看《终止监视器示例》
使用步骤前或步骤后子步骤代替默认模块
将步骤类型固有的基本操作的代码模块作为步骤前或步骤后子步骤来实现,而不是作为默认模块。仅当步骤的每个实例可以调用不同的代码模块时,才使用默认模块设置。默认的模块设置独立存在于步骤的每个实例中,而且当更改步骤类型的设置时,默认状态下,TestStand不会更新现有的步骤实例。但是,对子步骤的更改会自动影响相应步骤类型的所有现有实例。
为步骤类型创建编辑界面
编辑子步骤提供在代码模块中实现的图形用户界面(GUI),用户可以在编辑时在其中修改相应步骤实例的变量或设置。通常,编辑子步骤用于配置为步骤类型定义的自定义步骤属性。
示例:“打开数据库”步骤类型通过编辑子步骤提供了一个对话框,使用户可以配置ConnectionString和DatabaseHandle步骤属性,这两个属性是数据库步骤类型的自定义属性。
编辑子步骤提供了用于配置步骤设置的用户界面
用户创建自定义步骤类型的实例时,可使用步骤设置窗格中的按钮访问编辑子步骤用户界面,这将在新窗口中启动编辑子步骤UI。 不过,像许多内置步骤类型一样,也可以直接在选项卡中嵌入编辑子步骤用户界面。 这种方法需要额外的开发工作,并且必须使用.NET语言进行开发,但是这为步骤类型的用户提供了更加无缝的编辑界面。 关于如何实现嵌入式编辑子步骤界面的更多信息,请查看《在序列编辑器中创建自定义步骤类型编辑选项卡》。
嵌入式编辑界面(上)与在单独的窗口中启动的编辑子步骤(下)之间的比较
单个与多个编辑子步骤
一个自定义步骤类型可以定义许多属性,如果所有属性同时向用户显示,可能会造成混淆。 使用在单独的窗口中启动的编辑子步骤常用方法时,请在单个编辑子步骤中使用组织方法(例如引入选项卡)将数据组织到可管理的部分中。 由于每个界面必须独立启动,因此不建议使用多个编辑子步骤。 例如,“打开SQL语句”步骤可实现带有多个选项卡的单个编辑子步骤。
“打开SQL语句”步骤的编辑子步骤包含两个选项卡,可用于对设置进行分类
如果将嵌入式步骤面板方法用于复杂的步骤类型,则使用多个编辑面板的方法更佳,这是因为步骤选项卡上会清楚地显示数据。例如,“多数值边界测试”步骤包含两个选项卡,可用于编辑数值数据源和每个数据源的边界条件。
“边界”(Limit)和“数据源”(Data source)选项卡分别在单独的编辑面板中实现
将编辑子步骤模态化到TestStand
始终将编辑子步骤和其他用户界面代码模块模态化到TestStand,因为当TestStand调用编辑子步骤时,它将禁用序列编辑器。如果代码模块未模态化,TestStand窗口可能会隐藏代码模块。用户可能认为序列编辑器已挂起,并可能尝试终止TestStand。
关于如何在子步骤模块中实现模态化的更多详细信息,请参见将对话框模态化到TestStand示例。
表达式可用于充分提高灵活性
在编辑子步骤UI中使用表达式字段可帮助用户与数据进行灵活交互,并使用户可以在属性值中使用变量和逻辑。 但是,与使用字符串或数值控件相比,使用表达式控件需要更多的投资,并且需要进行额外的检查来确保表达式可为属性提供有效值。
指定设置时,表达式比固定值更灵活
定义开发人员创建步骤实例时的行为
在许多情况下,可能需要定义在测试开发人员创建新的步骤实例时出现的功能。 例如,内置的“If”步骤类型使用OnNewStep子步骤来插入匹配的“End”步骤。
为了实现这种功能,需要创建一个编辑子步骤,然后将该子步骤重命名为“OnNewStep”。 这些子步骤通常使用TestStand API来操作步骤实例或创建其他步骤实例。
对子步骤的通用建议
使用参数或TestStand API在子步骤中访问数据
与标准代码模块一样,将TestStand数据提供给子步骤的方法有两种。 可以通过代码模块的参数传递数据。 另外,还可以从代码模块内调用TestStand API,直接访问和更改属性。步骤前和步骤后子步骤通常只需要读取步骤属性即可确定其行为。例如,用于设置加热室的温度值。 但是,编辑子步骤需要将属性的当前状态显示在初始UI中,而且还需要一种方法来更新用户修改的任何值。
在大多数情况下,与使用TestStand API直接访问数据相比,使用参数传递数据是一种更好的方法。 使用参数更不容易出错:由于属性是在TestStand的步骤类型设置中定义的,而不是直接在代码模块中定义的,因此更容易发现属性名称或数据类型中的错误。此外,在步骤配置中定义所有属性可使步骤类型更易于维护。 在不修改代码模块的情况下,对步骤属性的任何更改都可以考虑。
但是,根据步骤的状态,当代码模块需要动态访问各种数据时,使用API直接访问属性可能很有帮助。 在这种情况下,使用步骤参数会导致参数过多,而在不同情况下,实际用到的参数只有一部分。
模块适配器将步骤变量读取或写入到代码模块的输入和输出中,并检查错误
在LabVIEW中使用TestStand API访问步骤属性不会在编辑时提供参数错误检查功能
编辑时卸载模块
在为自定义步骤类型的子步骤开发和测试代码模块时,请注意,在执行子步骤时,TestStand会加载代码模块并将其保留在内存中。由于模块将保持加载状态以供后续执行,因此这可以提高性能,但是在TestStand卸载模块之前,无法编辑代码模块。卸载代码模块的方法有两种:
- 选择“文件”(File)»“卸载所有模块”(Unload All Modules),卸载当前保留在内存中的任何模块。
- 在子步骤配置窗格中,选择“编辑”(edit)按钮,卸载模块并在相应的开发环境中打开模块
维护自定义步骤类型的最佳实践
存储和分发自定义步骤类型
应考虑如何存储和分发创建的自定义步骤,这一点很重要。NI建议在类型选板文件中(而不是在序列文件中)创建所有步骤类型,因为在加载序列文件时,TestStand会在类型选板文件中搜索步骤类型更新。TestStand还可以在序列文件中保留所使用的每个步骤类型的副本,帮助管理步骤的复用。如果在部署序列文件时未使用类型选板文件,序列文件仍将包含步骤类型的副本。
框架开发人员创建的步骤类型通常会分发给多个测试开发人员使用。 由于步骤类型具有许多关联的文件,因此这可能会带来一定的挑战。 为了帮助管理步骤类型文件,请使用以下目录存储步骤类型的文件
- 类型选板文件包含类型定义<TestStand Public>/Components/TypePalettes/
- 子步骤代码模块文件<TestStand Public>/Components/StepTypes/[typeName]
- 自定义图标<TestStand Public>/Components/Icons/[typeName]
通过使用这些目录,可将必要的文件分发到任何测试开发人员系统上的TestStand Public目录。 如果在新的类型选板文件中定义了类型,则可以对TestStand进行配置,在类型选板文件名中添加“Install_”前缀,自动导入类型选板。 关于此方法的详细信息,请查看“类型选板文件”帮助主题
避免重命名或更改步骤属性的数据类型
如果需要更改自定义属性的类型,可以使用新类型创建另一个属性,并保留使用先前类型的属性。如果更改了属性的名称或数据类型,TestStand会将步骤实例中的属性值替换为该属性的默认值。除了使用新类型创建新属性外,还可以向步骤类型添加逻辑,用于处理步骤同时使用旧属性和新属性的情况。例如,当TestStand将边界值实现为表达式时,它会添加两个新的布尔属性,用于指定使用旧的数值边界属性。UseLowExpr和UseHighExpr属性用于确定步骤是计算旧的数值边界还是新的表达式边界。