The following sections describe how you can use substeps to implement the following step type behaviors:
- Runtime functionality which should execute for all instances of the step type before or after the main code module
- User Interfaces to view and edit step data while editing test sequences
- Functionality to execute when the test developer creates new instances of the step
Substeps call code modules using one of the provided TestStand Adapters. Substeps cannot be modified in instances of the step, and all changes to substep settings will propagate to instances of the step type.
To add substeps to a custom step type:
- Navigate to the types view using the View » Types menu, or the shortcut key Ctrl + T
- Right click the step type, then select Properties…
- Select the Substeps tab. Choose the adapter which matches the desired code module
- Click Add, then select a substep type. A new entry appears in the substeps list
- Select the entry and click Specify Module to configure the code module for the substep in the same way as you would configure the code module for a step
Post and Edit substeps of the Multiple Numeric Limit Test Step Type
Defining Runtime Functionality for the Step Type
You can define runtime functionality for the step type using pre-step and post-step substeps. These substeps execute before or after the main code module when the step is executed.
Example: The message popup step type uses a C code module to create and display the message box at runtime. This module is called in a post-step substep,
Step Execution Order: Substeps
Use these substeps to define functionality that applies to all instances of the step. Often, substeps will require specific data related to the behavior of the step type. Define this data in custom step properties to ensure that it is available in all instances of the step.
If more than one Pre-Step or Post-Step substep exists, they execute in the order they appear on the Substep tab of the Step Type Property dialog box.
By default, test developers can specify a code module for each instance of the step type. If the step type does not require a code module, you should disable the “Specify Module” option in the Disable Properties tab for the step type configuration. Many built in step types are designed in this way, such as the statement and message popup steps.
Provide Visual Feedback for Long Operations
TestStand waits for code in Pre-Step or Post-Step substeps to execute before continuing. If code modules for those steps operate slowly or silently, TestStand might seem unresponsive. To address this, you can change the cursor or use UI messages, such as UIMsg_ProgressPercent, to update the progress bar in the status bar.
Refer to the Updating the Status Bar using UI Messages for more information on this approach
Use the Termination Monitor
Code modules you develop should include and periodically poll a termination monitor to gracefully handle when users terminate or abort sequence execution using the built-in options in TestStand or in the TestStand API. By using the termination monitor, you can quickly terminate the substep if the user terminates the sequence execution.
Refer to the Termination Monitor example for more information on implementing the termination monitor in your code
Use Pre-Step or Post-Step Substeps Instead of Default Module
Implement the code module for the basic operations inherent to the step type as a Pre-Step or Post-Step substep instead of as a default module. Use the default module setting only when each instance of a step can call a different code module. The default module setting exists separately on every instance of the step, and TestStand does not update existing step instances by default when you change the setting on the step type. However, changes to substeps automatically affect all existing instances of the step type.
Creating Edit Interfaces for Step Types
Edit substeps provide a graphical user interface (GUI), implemented in a code module, in which the user can modify the variables or settings of that step instance at edit-time. Typically, the Edit substep is used to configure custom step properties that you define for the step type.
Example: The Open Database step type provides a dialog via an edit substep to allow users to configure the ConnectionString and DatabaseHandle step properties, which are custom properties for the database step type.
The edit substep provides a user interface for configuring step settings
When the user creates an instance of a custom step type, they can access the edit substep user interface using a button in the step settings pane, which launches the edit substep UI in a new window. However, you can also embed the edit substep user interface directly in the tab, like many built-in step types. This approach requires additional development effort and must be developed in a .NET language, but provides a more seamless editing interface for user of the step type. Refer to Creating Custom Step Type Edit Tabs in the Sequence Editor for more information on how to implement embedded edit substep interfaces.
Comparison between an embedded editing interface (top) versus an edit substep, which launches in a separate window (bottom)
Single Versus Multiple Edit Substeps
A custom step type can define many properties which can be confusing if displayed to the user all at one time. When using the typical approach of edit substeps which launch in a separate window, use organizational methods within a single edit substep, such as introducing tabs, to organize the data into manageable sections. Using multiple edit substeps is not recommended because each interface must be launched independently. For example, the Open SQL Statement step implements a single edit substep with multiple tabs.
The Edit substep for the Open SQL Statement step contains two tabs to categorize the settings
If you are using the embedded step panel approach for complex step types, it is advantageous to use multiple edit panels, since the data will be easily visible on the step tabs. For example, the Multiple Numeric Limit Test step includes two tabs for editing the source of the numeric data and the limit conditions for each data source.
The Limit and Data source tabs are each implemented in a separate edit panel
Make Edit Substeps Modal to TestStand
Always make Edit substeps and other user interface code modules modal to TestStand because when TestStand calls Edit substeps, it disables the sequence editor. If code modules are not modal, the TestStand window can hide the code modules. Users might think the sequence editor is hung and might try to terminate TestStand.
Refer to the Making Dialog Boxes Modal to TestStand example for more details on how to implement modality in a substep module.
Use Expressions to Maximize Flexibility
Using expression fields in an edit substep UI is a flexible way for users to interact with data and allows users to use variables and logic in the property values. However, working with the Expression control can require a larger investment than working with string or numeric controls, and requires additional checking to ensure that the expression evaluates to a valid value for the property.
Expressions are More Flexible than Fixed Values for Specifying Settings
Defining Behavior when Developers Create Step Instances
In many cases, you may want to define functionality which occurs when a test developer creates a new instance of a step. For example, the built-in If step type uses an OnNewStep substep to insert a matching End step.
To implement this type of functionality, create an edit substep, and rename the substep to “OnNewStep”. These substeps typically use the TestStand API to manipulate the step instance or create additional step instances.
General Recommendations for Substeps
Using Parameters versus the TestStand API to Access Data in Substeps
Like with a standard code module, there are two methods for providing TestStand data to a substep. You can pass data through the parameters of the code module. Alternatively, you can call the TestStand API from within the code module to directly access and change properties. Pre-step and Post-step substeps typically only need to read step properties to determine their behavior. For example, the temperature value for setting up a heated chamber. Edit substeps, however, need the current state of the properties to display in the initial UI, but also need a way to update any values that the user modifies.
In most cases, it is a better idea to use parameters to pass data rather than the TestStand API to access them directly. Using parameters is less error prone: any errors in the property names or data types will be easy to find since the properties are defined in the step type settings in TestStand, not directly in the code module. Additionally, having all the properties defined in the step configuration makes the step type more maintainable. Any changes to step properties can be accounted for without any modifications to the code module.
However, using the API to directly access properties can be useful in cases where the code module is accessing a variety of data dynamically, based on the state of the step. Using step parameters in this case can lead to a long list of parameters where only some are used in various conditions.
The Module Adapter Reads or Write Step Variables to the Inputs and Outputs of Code Modules and Checks for Errors
Accessing step properties from within LabVIEW using the TestStand API does not provide parameter error checking at edit-time
Unloading Modules while Editing
When you are developing and testing code modules for substeps of a custom step type, be aware that TestStand loads and reserves the code module into memory when the substep is executed. This improves performance since the module remains loaded for subsequent executions, but you cannot edit the code module until TestStand unloads it. You can unload the code module in one of two ways:
- Select the File » Unload All Modules to unload any modules currently reserved in memory.
- In the sub-step configuration pane, select the edit button to unload the module and open it in the corresponding development environment
Best Practices for Maintaining Custom Step Types
Storing and Distributing Custom Step Types
It is important to consider how to store and distribute the custom steps you create. National Instruments recommends creating all step types in a type palette file, not within a sequence file, because TestStand searches the type palette files for step type updates when you load a sequence file. TestStand also helps you manage the reuse of steps by keeping a copy of each step type used inside a sequence file. If you deploy the sequence file without the type palette file, the sequence file still contains a copy of the step type.
As a framework developer, it is common that your step types will be used by multiple test developers. This can be a challenge, since step types have many associated files. To help manage the step type files, use the following directories to store the files for your step type
- Type palette file containing the type definition <TestStand Public>/Components/TypePalettes/
- Substep code module files <TestStand Public>/Components/StepTypes/[typeName]
- Custom icon <TestStand Public>/Components/Icons/[typeName]
By using these directories, you can distribute the necessary files to the TestStand Public directory on any test developer systems. If you defined your type in a new type palette file, you can configure TestStand to automatically import the type palette by adding an “Install_” prefix to the type palette file name. Refer to the Type Palette Files help topic for details on this method
Avoid Renaming or Changing the Data Type of Step Properties
If you need to change the type of a custom property, you can do this by creating another property with the new type and retaining the property with the previous type. If you change the name or data type of a property, TestStand replaces the value of the property in step instances with the default value of the property. In addition to creating a new property with the new type, you can add logic to the step type to handle cases where a step uses the old property and the new one. For example, when TestStand implemented limit values as expressions, two new Boolean properties were added to specify to use the old numeric limit property. The UseLowExpr and UseHighExpr properties determine if the step evaluates the old numeric limits or the new expression limits.