TestStand User Interface Development Best Practices


A TestStand User Interface is an application that provides a graphical interface for executing tests at a production station. You typically use a user interface application to execute tests and use the TestStand Sequence Editor to develop tests. You can customize the user interface to suit your specific testing needs or even to develop tests, if needed.

This article discusses the best practices for designing and developing your TestStand User Interface application:

  • Describes the components that TestStand provides out of the box
  • Explains how to utilize the TestStand architecture to build an expandable, maintainable test system


Architecture of a TestStand User Interface

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 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:

  • Seamlessly interact with a test system using multiple different user interfaces.  For example, a test developer can use the sequence editor to develop sequences, while a test operator uses an operator interface to execute tests and view results.
  • Make changes to the UI without the risk of changing the behavior of the test itself.

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.

TestStand User Interface (UI) Controls

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.

Manager Controls and Visible Controls

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

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.

Simple and Full Featured Example User Interface Applications

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:


Managing the Needs of Different Users

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:

  • Framework Developer – designs test framework components, including customized user interfaces, process models, and step types.  
  • Test Developer – creates test sequences within the framework implemented by the framework developer.
  • Technician – troubleshoots problems with tests running in a production setting.
  • Test Operator – sets up units for testing and runs the tests in a production setting.

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

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
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.


Functionality to Implement Outside the UI

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.

Implement Initialization Code in Front-End Callbacks

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:

  • All TestStand user interfaces and the sequence editor call the same LoginLogout sequence, allowing you to define functionality you can access from any UI, and avoiding duplicated code
  • You can make changes to the behavior of your additional code without needing to make changes to user interfaces.

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.  

Use the Tools Menu to Access Supplemental Applications

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
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.

Use Process Models to Define Sequence Entry Points

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.


Communicating between the User Interface and Other Components

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.

Communication between the Sequence and the User Interface

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:

  1. Independence of UI and sequence files - A user interface should always run with any sequence file, and vice versa.  By using UI messages, there is no requirement that certain properties exist in sequence files when using them with the user interface.  With UI messages:
    • The user interface can execute sequences that do not implement certain messages (the handling code in the user interface simply never executes).
    • Sequences that post custom messages can be executed in a UI that is not built to handle them (the UI message is just ignored by the user interface).
  2. Maintainability - UI messages avoid dependence on Sequence File Properties or UI variables, meaning less to maintain for developers of both sequence files and user interfaces.

For more information on using UI messages, refer to Using TestStand User Interface Messages (UI Messages)

Types of 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:

  • UImessage event - this event is fired whenever any UI message is handled by the Application manager.  The event callback specified will execute before any default UI message handling operations.  The cancel output event argument can be set to True within the callback to override the default event operations.
  • UserMessage event - this event is fired only for custom UI messages (those with message ID of 10,000 or greater).  

For information on defining event handlers for a user interface, refer to the Handling Events topic in the TestStand help.

Communication from the User Interface to the Executing Test

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


Was this information helpful?