LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Testing State Machine Code (and Feedback)

Hi,

I am working on developing a DAQ from an existing test system. I have a questions related to program architecture (getting feedback for scalability) and testing my code. As my program is getting larger I wanted to make sure I am following right practices to avoid pain later down the road. Right now I am using a Producer/Consumer Architecture and within each loop I am using State Machines. 

 

As I keep adding features, I am having hard time to test my code before releasing it to production. I reviewed the unit test framework Caraya (from JKI) and learned how to develop test cases for subVI and ultimately a test suite that will give confidence that I didn't break anything that was working fine before. However, I do not know how can I incorporate or develop test cases that will help me test the flow of my program i.e. Integration testing. I have been doing it manually (i.e. going into different states and injecting data for testing, and later deleting it) right now, and using highlight execution is very time-consuming. There must be some practices used during the development for testing the entire program (if there is not a framework or tool), and I am seeking help from this community to guide me on that. 

 

I have attached my project files along with this post if required. Therefore, I would also appreciate it if I could get some feedback on the code as well. I do not expect someone to go through in detail but quick review and feedback will be highly appreciated.

0 Kudos
Message 1 of 3
(1,149 Views)

I personally find that the best method to get full coverage on test code without having actual hardware present is what is known as "hardware-in-the-loop" testing.  It's not something super easy to set up for a beginner though.

 

You start doing it at first basically by making your code modular.  You need to separate all instrument code into abstract calls that run in some sort of separate area (parallel loop, asynchronous VI, or even a completely different program or PC, depending on the situation).  So you'd never just have a raw "VISA Read" in your main state machine anymore.

 

If you made your code modular enough and implement it correctly, it should be simple enough to set up a toggle between two separate modules with very little effort.  You just have a little switch that you can flip right at the very start of your code to switch between the two.  One module is the "real" code, and the other is simulation code, and that one flip switches your entire code to simulation mode or to real mode.

 

The key is that the code you write for simulation mode needs to be something that can simulate as much of what your instrument might do as possible.  Either automatically in the background, or running a script, or whatever else works best. 

 

As an example, I often test lasers, so I will write code to simulate testing by having the simulated power supply just cache whatever power value I send to it, and then when I check the laser power meter to see how much light the laser is putting out, it queries the cached value from the power supply, applies a conversion formula, and returns that as the power reading (after a short programmed delay to simulate measurement time).

 

Sometimes my simulation is just a log of all commands sent, if a device is pretty much a passive one that doesn't provide any active feedback, and I just look at the logs later to see if it was sent the right commands at the right times.

 

Other times my simulation devices are actually separate VIs running with their front panel showing, and I can change settings on those front panels to simulate different hardware events happening.  I might have one event to simulate someone pressing an emergency stop button, another to simulate readings from a bad part, another one to simulate an overheating unit, etc... you just have to use your imagination sometimes.

 

As for a framework on how to do something like this, the Actor framework is pretty handy if you can set it up correctly.  Set up two actors per device, one for real hardware and one simulated, make sure they accept the same messages, then start up the real ones normally but have an option to switch to the simulated ones for testing.  You could also just use LVOOP for all of your instruments, with an abstract parent class that you do all of your calls in, and then put either the real class or the simulation class on the wire when you start up.  Both of those might be a bit advanced for where you are now though, based on a quick peek at your code.

Message 2 of 3
(1,133 Views)

Hi Kyle97330,

Thank you for your response and idea.

 

I also have implemented similar to what you have suggested testing the rest of the code to simulated device data, and have a boolean named Test Enabled visible in the block diagram. However, I was looking for automated testing which will give me results (test pass or fail) for my application as a whole. For subVI, we have Unit Test Framework but I could not find something similar for the integration testing. However, reading through your detailed post I got an idea that may be I start adding a test code in the state machine that gets enabled when I have the test flag as true. However, this will be a fix for now but still it a manual testing and relies on someone validating the results.

0 Kudos
Message 3 of 3
(1,065 Views)