Example Code

Simple Teststand User Interface API for LabVIEW

Code and Documents


Version 2+: Following feedback I have improved the package to contain the examples as well as a project template. A default action has now been defined for the most commonly used callbacks. These changes will greatly simplify the use of this API/framework


Version 7: Repackaged API


Introduction: The pain

When going through the Teststand training it becomes apparent that the sequence editor should never be part of a finished test system. Instead a customised user interface should be deployed which operates on the “kiss” principle, only exposing what the operator needs for his/her job.


When you ask people about the possibility of creating a Teststand user interface in LabVIEW the feedback will frequently involve something like “yes, it is possible but DON’T!”. When looking at the examples that ship with LabVIEW you find a very incoherent story. The architectures (if you want to call it that) in those two examples bear no resemblance to one another and generally offer little opportunity to use them as the basis for your own project: The full UI example declares already in the opening lines that it is an example adopted from a different programming language and that it has no intention to follow LabVIEW programming paradigms or data flow in general. Everything is defined as global variables making this a convoluted and frustrating experience to try to understand:

global variables.png

Or how do you feel about this (it continues nearly indefinitely to the bottom …):

callback registration.png

The simple UI example is a bit better in that respect and particularly LabVIEW 2014 features a revised simple UI which confines it to a state machine but I still don’t consider it a solution to the problem.

When talking to some of the top Teststand people at NI it became obvious why we have this pain when trying to develop a custom user interface for LabVIEW. The phrase “It all makes sense when you know how to program .net” still rings in my head. As it happens a lot of people programming with LabVIEW DON’T know how to program .net.


The aim:

Writing simple proof of principle examples should not be difficult. I just talked to one of the in my opinion best LabVIEW programmers in the UK who just echoed that. It looks like he might need a custom Teststand UI for a future project and decided to “quickly” set up an example on a Friday afternoon. I don’t think his wife appreciated that she didn’t get to see her husband all weekend!

As part of a previous project I tried my best to wrap as many of the nasty bits of the examples away and actually make it look like LabVIEW code (at least on the top level). Afterwards I decided that it must be possible to do better than that and that it must be possible to properly wrap things in a way that the existing painful LabVIEW/.net/ActiveX hybrid actually behaves like modern object oriented code.


I wanted a strict architecture that will work for nearly everything you might want to throw at it.


I wanted it to be possible to set up an example in 5 min!


The gain:

(I'll stop rhyming now, promised!) You can test further down if I have achieved a target of 5 min to create a simple example. I definitely hope that you won’t have to extend a Friday afternoon project over the weekend anymore.

The idea is simple: There is a base class which wraps all the common functionality (i.e. control registration, callback registration, etc.). For your application you will need to create a child class which implements all the application specific bits. Bits which are alien to LabVIEW like callback registration are dealt with by override Vis and thus start to better follow object oriented LabVIEW programming paradigms.

The structure of an applications is as follows:


  • You register your control references using the class property nodes
  • You go through the initialisation stages (pre-engine init, engine init & post-engine init)
  • You use the event registration of the generic Teststand user event to handle Teststand talking back to your main application
  • On shutdown there is some tidying up happening


The examples (re-writes of the original examples) which I provide tell a coherent picture. The structure is identical in all of them as can be seen in the following.

Multi window example:

multi window example.png

Simple example:

simple example.png

Full user interface:

full example.png


Setting up your own application

Supplied with this article is a VI package. You will need to install the package with the VI package manager as well as having LabVIEW and Teststand installed to be able to follow this simple example.


You will now create your own basic Teststand user interface. On the LabVIEW start screen click on Create Project:

Labview start screen.png

Select Templates: Teststand:

Teststand template.png

Click next, under project root browse to a path where you want to save your project. Once you are done, click Finish. Subsequently your new project opens which already contains a top level vi (Teststand User interface.vi) as well as your Teststand child class (Teststand Application.lvclass😞

Teststand project.png


Now open the Teststand User interface.vi file. Right click on the front panel and navigate to the Teststand palette:

teststand pallette.png


Drop a sequence file view manager, an execution view manager, two buttons and a sequence view onto the front panel. Change the name of one button to Load Button and the other button to Start Button. Change the name of the sequence view control to Execution View. All in all it should now look vaguely like this:

Teststand front panel.png

Now switch to the block diagram and connect the controls to the property node at the beginning of the application. You will have to extend the property node for this. The controls have to be linked up as follows.


  • Execution view manager link to ExecutionView Manager
  • Sequence File view manager link to SequenceFileView Manager
  • Load Button link to Open Sequence File Button
  • Execution view link to Execution View
  • Start Button link to Entry Point 1 Button


This should now resemble this:

quick example BD.png


Start now the application, clicking the Load Button will prompt you to select a sequence file, clicking the Start Button will call the Test UUT entry point. The execution trace will be displayed in the execution view. When everything is finished close the application by clicking the close window button ("X"). The application automatically shuts down, releasing all resources. If everything has been working correctly you will have successfully created a Teststand user interface.


You will have noticed that you didn't need to do anything to be able to use the Start Button as well as the execution view. This is because a default action has been defined for the most frequently used callbacks. I.e. if you would want to implement a report view you would need to create a callback yourself. You would do that by right clicking the Teststand Application.lvclass in the project | New | Vi for override ... | Display report event callback.vi


For a possible implementation of this callback vi you can take inspiration from the examples which are shipped with the simple Teststand API package. Access these via Help | Find examples ... | Browse according to: Directory structure | Teststand | Simple Teststand API | New Teststand API.lvproj


User events

To be able to talk back to your main application from the teststand callbacks a generic user event is included with a typical string command/variant payload event data. You should be able to easily mix this with your own user events doing something like this:

user event merge.png

The “user event handling.vi” override vi allows you to implement a state machine to deal with incoming events. Take a look at the examples to see how this can be done.


In addition it is also possible to create Teststand user Messages which can be handled in the User Message callback.


Wrapping up:

I hope you find this useful. I am completely aware that this is not polished and potentially buggy: I don't take any responsibility, use at your own risk. Please give feedback if you can so that this can evolve into a useful tool for everyone.


change log:



- initial release



- updated package to include examples. Location: Help | Find Examples ... | Browse according to directory structure | Teststand | Simple Teststand API

- included the most common callbacks as default (Exit application, wait, display execution, display sequence file, Report error). Only need overriding if you want to change the default action.

- included project template. Access by: start screen | create project | Template:Teststand

- added Teststand user message callback to allow sequences to better interact with the user interface



- removed old packages

- corrected typos



- repackaged API


04/01/2016 (happy new year everyone!)

- downgraded package to support LabVIEW 2012 (not fully tested: I left the previous 2013 version in case you encounter a problem with the 2012 version)



- moved "reload all sequence files" to the pre-engine init in order to allow for it to get overridden

- added safeguards to all data access VIs to ensure that inserted null references do not cause an error

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.



Can you please package this to be compatible with Labview 2013.




Hi Yogesh,

thanks for your interest in this package. What are your problems when installing it with LabVIEW 2013.

I originally developed it for LV2013 and then downgraded it to LV2012. I installed both packages on LV2012, 2013, 2014 & 2015 without problems. Can you give me a bit more information so that I can try to get you up and running, please?

Best Regards




      我在尝试能否用labview的table控件代替teststand的Execution Display控件,但目前还是没找到方法。你是否有此方面的经验可以分享。谢谢


      I'm trying to replace the execution display control of TestStand with the table control of LabVIEW, but I still haven't found a way. Do you have any experience to share. thank you