Random Ramblings on LabVIEW Design

Community Browser
Labels
cancel
Showing results for 
Search instead for 
Did you mean: 

Functional Programming / Immediately Testable VIs

Active Participant

Hello Lovelies

Out of all the presentations I have produced I like the immediacy one the best. In it I talked about functional programming and what I now call Immediately Testable VIs (ITVI). Thanks to James Mac for the terminology clarification.

 

The thing for me that makes LabVIEW stand out from the software crowd is how close you are to the final running bit of software.

 

Let's look at a simple VI.

SimpleVI.png

We can tinker with it, probe it and change stuff. If you program in text based languages this is pretty fantastic stuff.

 

Now we stick a framework around our code, giving us all sorts of useful stuff. But with every benefit, there is usually a cost.

 

As an example I'm going to pick on Actor Framework but I imagine this applies to any framework (including our own SSDC templates). All of the Actor framework projects I've been exposed to have a very low percentage of VIs that you can just run and experiment with. To clarify it means that a VI cannot run on it's own, it needs the whole or part of the framework to be running to be able to run itself. I call this Framework Coupling.

 

Variant.png

Here's our queue component and it is a non-ITVI, to test this VI I would need a teststub or to run the entire application.

 

As we design we need to think about framework VIs and ITVIs and we need to keep them separate. That way we can get all the advantages of LabVIEW in the parts we need it and the carrier VIs etc for your framework just get on with their work.

 

So here's an example from a client, they had an actor that talked to a VISA instrument and the comment was "I like Actor Framework but it's hard to debug", my response was to suggest putting all the VISA stuff in a standard VI that you can just run to completion. I then suggested that they should then separate out framework VIs from VIs that do stuff. And magically it wasn't so hard to debug any more.

 

I know it's a pretty simple concept, but I've described it to enough experienced programmers and it's been helpful to them, maybe it will help you too.

Lots of Love

Steve

 

 

 

 

Comments
Active Participant

Steve mentioned one of my favorite topics (Actor Framework), so I'll weigh in.

 

First off, I completely agree with the concept.   It does take more effort (and code) to test an actor, and wrapping the meat of your actor's code in a set of testable VIs is a fabulous way to reduce that effort.  Once you've proven those component VIs work, you can say with a fair amount of confidence that any problems with the actor are in the messaging, or perhaps in the way you've structured your helper loop.

 

If it makes sense, convert that set of VIs to a class.  It's only a little bit harder to test, and really only as hard as testing the API for a driver.  But now you start to allow for changing one class for another, which means you can get different behaviors for the same set of actor messages.  Your DMM actor can now use NI or Keysight hardware, for example, while preserving the same messaging.  This way, the bit of extra work you do to make your code more testable may also advance the project in a meaningful way, instead of just mitigating a negative.

 

Take a look at Network Endpoint Actors for an example of how this might work.  Network endpoints can use TCP/IP or Network Streams, but the rest of the system only sees network endpoints.  I did exactly as Steve suggested:  I wrapped the TCP/IP and Network Streams APIs into classes.  When it came time to test my code, I was able to test my protocol VIs independently.  When I was sure they worked,  I plugged them into an actor to test messaging.

 

Secondly, it's worth remembering that AF actors are LabVIEW classes, so to some extent, you can actually test them as Steve describes.  Drop the actor's methods on a block diagram, and test them as you would any other LabVIEW class.  There are limits, of course; you can't test Actor Core, and you're limited on what you can do with messages the actor sends or receives.  But for some actors, this can be very helpful.

 

Finally, and I suspect this is true for most frameworks, it helps to understand what code you actually need to test, and what can be safely ignored.  AF projects tend to have a lot of code, but a hefty percentage of that goes into message classes.  This is script-generated glue code, and one of the advantages of having a framework is that you get to ignore that.

Active Participant

Thanks for your input, most appreciated Mr Smith.

The point I'm trying to make is that we can encapsulate the stuff that is just primitives and data (i.e. the functional parts) and have them separate to the non-ITVI stuff. I would place Classes as non-running carriers too. That said, what you suggest is also completely valid. I think consideration for testing as you design may be the way forward.

 

Completely agree with your final point. I could have quite easily shown an example of our queued state-machine template to demonstrate my point. I've applied these techniques to our templates and it's been very useful.

 

An example would be ...

Prior to this I would have a component that got data from a database and converted/parsed and manipulated it in the same component. Now I separate the getting data from database bit (non-runnable) from the data manipulation bit (functional). The idea is to keep the key benefits of LabVIEW and also have the benefits of a framework.

 

Cake and eating it!