This article discusses the best practices for designing and developing your TestStand User Interface application:
TestStand is designed using a modular architecture, utilizing distinct components that each have a single purpose, which makes development and maintenance of the entire system more straightforward.
The user interface is a distinct component within the modular TestStand architecture
The user interface component provides the mechanism for developers and test operators to create and run the sequences in a test system. In a modular architecture, a clear boundary should exist between the UI and the underlying TestStand application. This has the following benefits:
TestStand User Interfaces communicate with the TestStand Engine API to perform their various functions, such as getting the state of test executions, creating and editing sequences, and configuring settings. TestStand also provides a set of user interface controls and a separate UI API which allows you to quickly create your own TestStand User Interfaces.
The TestStand User Interface (UI) Controls are a set of ActiveX controls that implement the common functionality that applications require to display, execute, and debug test sequences. These ActiveX controls significantly reduce the amount of source code that a user interface requires to interact with the TestStand API to handle user interface tasks. You can use Properties pages or call the available properties and methods to configure these controls. Refer to the TestStand UI Controls help topic for more information about how to use the TestStand UI Controls in LabVIEW, CVI, C#, or VB.NET.
The TestStand UI controls provide two sets of user interface controls: manager controls and visible controls.
Manager controls call the TestStand API to perform tasks such as loading files, launching executions, and retrieving sequence and execution information. Manager controls also notify you when application events occur, such as when a user logs in, an execution reaches a breakpoint, or a user changes the file or sequence they are viewing. Manager controls are invisible at run time.
Visible controls display information to the user, such as an execution view control which shows the current execution status. Visible controls also allow the user to interact with the UI, such as using a button control to execute a test. Visible controls must be connected to a manager control to define how they function. This connection is implemented using connection methods of the manager controls. When you connect controls, the internal logic of managing the behavior of the visible control is handled automatically by the manager controls. You can make view connections, list connections, command connections, and information source connections, depending on the type of manager control and visible control you connect, and the desired behavior of the visible control.
Connect Visible TestStand UI controls to manager controls to define their behavior.
For more details on using the TestStand UI controls in different programming environments, refer to the TestStand User interface Controls help topic. You can also use the Connecting UI Controls Demo to see the behavior of the available connections you can create.
Additionally, you can use the controls natively provided in your programming environment alongside the TestStand UI Controls. When working with native controls, you can use the User Interface API to communicate directly with the manager controls to implement TestStand related functionality. Refer to the Building a TestStand UI with Native Controls Example for more information about writing an application that directly calls the TestStand API.
TestStand provides several examples and components that you can use to help you build a user interface. The example user interfaces provide a starting point for developing a custom user interface. TestStand also ships with user interface components that implement common features used in these applications that you can reuse in your own applications.
TestStand ships with a simple and full-featured user interface application example in supported programming languages, including LabVIEW, Labwindows™/CVI™, C#, and VB.net. TestStand provides source code for these examples in each of the supported programming languages. You can use this source code as a starting point for developing a custom user interface or you can use them as-is.
The simple user interface has a minimal display, does not include a menu bar, and is intended as an interface for test operators on a deployed test system. The full-featured user interface displays more information, includes a menu bar, and provides debugging capabilities. The full-featured user interface also has an editor mode that allows you to create and modify test sequences, like the TestStand Sequence Editor.
The simple User interface examples are a great place to start when learning how to develop using the TestStand UI controls. For the LabVIEW, LabWindows/CVI, or C# implementations, you can use the following guides for a detailed description of the source code and how it works:
When developing user interfaces for a test system, it is important to consider the objectives and needs of all users who will be interacting with the application. Test system users can typically be categorized into the following roles:
In planning and designing appropriate user interfaces for test system users, you are taking on the framework developer role. The TestStand UI controls allow you to fully customize your user interface based on the requirements of your users. For example, a test operator may only need to have the ability to start a test and see the result. A test developer, however, needs to have full access to creating and editing sequence files.
You can provide test developers with a full-featured user interface which allows creation and editing of sequence files, such as the full-featured UI example or sequence editor provided with TestStand. For test operators, you can design a simple user interface which exposes only a button to start testing, and an indicator showing the result of the test, to ensure operators can successfully run the test. Providing a UI to operators that is more complicated can be problematic, since it requires additional operator training, and is error prone due to the available functionality.
By using the TestStand UI controls to develop the UI, you will be able to seamlessly migrate from the full featured UI to the simple UI. Both UIs are built on the TestStand engine, sequences, process models, and other components, which are shared by both UIs.
Full Featured UIs such as the sequence editor and simple operator UIs can seamlessly interact with the same test code
In addition to creating separate user interfaces, you can also use TestStand user management to customize what features are made available in a single user interface application. This approach is better in cases where different roles are working with the same test executions. For example, a technician responsible for troubleshooting test failures will need access to diagnostic data, such as a view of the execution and/or test report, which are not typically exposed to operators. Having a separate UI application for the technician would be problematic since they would not have access to the current execution information from the separate application. To address this, you can create a single user interface which unlocks additional views for more advanced users. For example, the TestStand full featured User Interface can be changed to editor mode using ctrl + shift + alt + insert to provide advanced users with the ability to make changes to sequences.
The full featured UI example can execute in operator mode or editor mode
When you define users for the TestStand user manager, the TestStand UI Controls automatically enable or disable their state based on the privileges of the current user. You can also define custom behavior based on user privileges with the Engine.CurrentUserHasPrivilege TestStand API method, for example hiding or showing certain portions of the user interface. Refer to the Managing Users help topic for more information about defining users and privileges.
When developing a TestStand User interface, it is important to define a clear line of what is implemented in the UI versus other components of the test system. This section outlines common test system functionality and where it should be implemented within the TestStand architecture.
In many cases, a test system requires that actions be performed before the test starts executing. For example, you may need to initialize test hardware and validate that it is calibrated, or check for user privileges to initialize the user interface.
To handle these functions, you can use the LoginLogout sequence in the Front-End callbacks sequence file. This sequence is executed by default by the TestStand UI application manager control when TestStand starts, and by default displays the login dialog to the user. Adding functionality to this sequence has the following benefits:
In addition to the LoginLogout sequence, you can define additional sequences in the front-end callbacks to implement functionality called at a different time. For these additional sequences, you will need to add code to the user interface to call the sequence at the desired time, using the Engine.CallFrontEndCallbackEx() method. This approach is convenient because you do not need to manage a reference to a sequence file, since the Front-End callback is loaded and unloaded automatically by TestStand.
A test system often utilizes separate tools or applications that work alongside the test. For example, you might launch a database configuration utility or an analysis application. Rather than building these functions as modules of a user interface application, you can modularize your system by implanting standalone tools, and provide access to them through custom tools menu items. You can customize the tools menu from the sequence editor using the Tools » Customize menu. In the customize dialog, you can add new tool menu items and configure their behavior.
Create custom tools to provide additional functionality to any user interface that implements the tools menu
Changes you make are saved to a separate configuration file, so all user interfaces will display the same custom entries you create. For more information, refer to the Customize Tools Menu Dialog Box help topic.
A user interface needs to provide a way for users to start sequence executions, but it is important that the UI is not directly coupled with any sequence file. To allow users to start tests, You can create a button which calls an execution entry point of the currently loaded sequence, including either running the sequence directly, or using a process model entry point, such as Single Pass and Test UUTs. The user interface should not contain functionality which executes before or after a sequence execution; instead implement this functionality through the process model.
The process models can also define configuration entry points, which allow users to configure process model settings. Ensure that any model settings are configured from these entry points, and not directly through the user interface. By building features into the process model, the features become available in any TestStand user interface application and the sequence editor.
For more information on using process models, refer to the Best Practices for TestStand Process Model Customization document.
While it is important that the user interface is decoupled from other components of the test system, such as test sequence files and process models, it is necessary for the user interface to effectively communicate with these components. This section provides approaches you can use to communicate between these components while still maintaining this modularity.
While a test is executing, the test system must provide feedback to the operator indicating the current state of the execution, such as which test is running or the current test results. In general, you can use TestStand UI controls to display this information, such as an Execution View and Report View. By connecting these controls to a manager control, they will always update to show the current execution state, as managed by the engine.
In some cases, you may want to display more specific information about the test. The executing sequence or code module must pass this information to the user interface for display or instruct the user interface to take action. In order to communicate this information without introducing coupling, you can use UI messages to implement the communication. The alternative of using a sequence file property or UI variable as a means to communicate creates unwanted dependencies between sequence files and the user Interface. For example, updating a file global from the sequence, then checking its status in the user interface introduces a coupling between the global and the UI. UI messages are preferred for two reasons:
For more information on using UI messages, refer to Using TestStand User Interface Messages (UI Messages)
UI messages contain a message ID which indicates the purpose of the message. TestStand defines several UI message IDs, which define messages that are either sent by the engine automatically or are automatically handled by the TestStand user interface controls. For example, the message ID UIMsg_EndExecution (value 4) is sent by the engine after an execution ends. The Manager controls expose many of these UI messages as individual events; in this case, you can define a handler for the ApplicationManager EndExecution event rather than using a UI message event handler directly.
Other UI messages are posted by the default process models, such as the UIMsg_ModelState_Identified (Value: 32), which the process models post after identifying the serial number of the UUT. In addition, you can post predefined or custom UIMessages from your code modules, test sequence(s), or the process model using the Thread.PostUIMessageEx TestStand API method.
A list of UI message IDs, or event codes, can be found in the UIMessageCodes help topic.
You can define your own UIMessages for custom operations, such as updating data in a chart and histogram. When you define custom UIMessages, specify unique event codes starting at the UIMsg_UserMessageBase event code When you post a custom UIMessage, pass the defined event code and the data to be displayed. UI messages provide data fields for numeric, string, or ActiveX data which you specify when calling the postUIMessageEx method. When you define a handler to respond to the UI message in your user interface, this data is exposed as parameters in the event callback.
To define how a user interface handles UI messages, configure the operator interface to run user defined code when a UI message is handled by adding an event callback for one of two Application Manager events:
For information on defining event handlers for a user interface, refer to the Handling Events topic in the TestStand help.
In some cases, you may want to communicate information from the user interface to the test sequence. However, communication between a sequence and a UI should always be initiated by the sequence, to ensure the sequence is in a state where it’s data can be modified. To accomplish this, the sequence can post a UI message with a custom code, indicating that it is ready for communication. When you post the UIMessage, set the synchronous parameter to True so that the execution waits until the user interface processes the message. When the user interface processes the UIMessage, it retrieves the SequenceContext object and writes or reads certain variables, such as the process model local variables.
In many cases, the UI is not the best place for the user to specify data related to the test. For example, if the data relates to tasks in the process models, a better approach would be to modify or create a configuration entry point, which you can access from the default menu.
For an example demonstrating Posting and Handling UI messages, including using UI messages to gather data from the user interface, refer to the Handling UI Messages shipping example