Jump to content

Search the Community

Showing results for tags 'oop'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Software & Hardware Discussions
    • LabVIEW Community Edition
    • LabVIEW General
    • LabVIEW (By Category)
    • Hardware
  • Resources
    • LabVIEW Getting Started
    • GCentral
    • Code Repository (Certified)
    • LAVA Code on LabVIEW Tools Network
    • Code In-Development
    • OpenG
  • Community
    • LAVA Lounge
    • LabVIEW Feedback for NI
    • LabVIEW Ecosystem
  • LAVA Site Related
    • Site Feedback & Support
    • Wiki Help

Categories

  • *Uncertified*
  • LabVIEW Tools Network Certified
  • LabVIEW API
    • VI Scripting
    • JKI Right-Click Framework Plugins
    • Quick Drop Plugins
    • XNodes
  • General
  • User Interface
    • X-Controls
  • LabVIEW IDE
    • Custom Probes
  • LabVIEW OOP
  • Database & File IO
  • Machine Vision & Imaging
  • Remote Control, Monitoring and the Internet
  • Hardware

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Company Website


Twitter Name


LinkedIn Profile


Facebook Page


Location


Interests

  1. Hi, I posted this question in OOP forum, but may be the right place is here... Have you experienced that LV takes very long time to build executables when you use a certain number of classes? I have noticed that when my app uses many classes (e.g. 30 classes) LabVIEW IDE slows down ("busy pointer" appears very often during VI editing) and compiling executables takes more than half an hour. It's not due to my machine because larger projects are built in less time if they don't contain so many classes. Are there properties that can speed up the build?
  2. Hello, I am developing a PXI system and thought I would use OOP to do all the DAQmx calls for all the different cards in my chassis. It all looks nice and neat and works a treat when running in LabVIEW 2013. All my Network Shared Variables are updated on my host application and the host can happily control the PXI chassis. However, as soon as I try and create an executable to run at startup the code stops working, it simply appears not to deploy. There are no errors or warnings, the PXI executable simply no longer works. I presume I am missing something simple, like a missed check box or an automated deploy command. If anyone can see what I might be doing wrong then I'd be mighty grateful. My class structure is fairly simple LabVIEW Class >> DAQmx Class >> PXIe 6363 AI, PXIe 6363 DI, etc Thanks Malcolm
  3. Hi Everyone, This is my first post and am just beginning to learn OOP so please bear with me. I was curious on whether when you use a DVR to encapsulate a class i.e. force an initialization to occur before other methods, and then close the reference to that DVR. Is the class removed from memory completely or is it just the reference that is cleared. Thanks!
  4. Hi, Here comes a rather basic question but which I'm always struggling with since you can often argue both ways. Hopefully some of you have a few nuggets to share here... 1) A parent class should have no knowledge of any child class' concrete type, i.e. only data and methods that is inherently common to all decendents of that parent should be defined by it. 2) For dynamic dispatching to work the parent class must define virtual methods for dynamic dispatchees to work from. Those two rules often contradict each other. Methods vetted against 1) will often eliminate the possibility of 2). A specific example: Currently at GPower we're working on a set of classes that enables us to do a lot of stuff on all the different LabVIEW files. So, we have a parent file.lvclass and then a collection of specific children that inherits from "file", for instance vi.lvclass, lvproj.lvclass, ctl.lvclass, facadevi.lvclass etc. A) Generic stuff that has to do with any file obviously goes into file.lvclass data (together with data member access methods for each). For instance IsWriteprotected?, FileSize, FilePath and such. A FileRefnum should probably go into each child class to enable us to have it most specific. B) Then there are data elements that definetely has to do with each concrete file type and thus should be in each child class' private data, such as AllowsDebugging?, IsFPStyleOK?, Icon etc. - as those are only valid for a subset of file types. C) Now it gets a bit more murky; If we define data elements in file that each child can use to flag if it has this or that feature (like HasIcon? or SupportsProtection?), then you can ask each and every file type if it support that, before calling a method to work on that. For the subset of file types that supports a given feature (those that has an icon for instance) it'd be great to have dynamic dispatching though. But for that to work file.lvclass would have to implement virtual methods like GetIcon() and SetIcon() (where the latter maybe recalculates the IsIconStyleOK? data field for instance). But implementing these (numerous it turns out) virtual methods in the parent class, suddenly riddles the parent class with specific knowledge or nomenclature that is very specific to different subsets of descendent file types. I always vet the parent against each piece of information I'd like to put in there by asking myself something like this: Does my generic file know anything about disk write protection? Yes, all files deal with that, so it can safely go into file.lvclass. Does my generic file know anything about block diagrams? No, only a handful LabVIEW file types knows about block diagrams, so I can't put it into file.lvclass. But the latter forces me to case out the different file types in my code, so I can call the different specific methods to work on block diagrams for those file type objects that supports this. Hence, if I want to be able to just wire any file type object into a "block diagram worker" method I need dynamic dispatching, and that only works if my parent has a virtual method for me to override with meaningful code in a few child classes... How do you go about selecting this balance, on one hand abstracting the parent from the concrete types, and on the other hand implementing the necessary dynamic dispatch virtual methods in the parent? Regards, Steen I must add that I'm currently leaning towards the more pure approach of not mixing abstract and concrete. Thus I tend to omit dynamic dispatching except for the very generic cases. I only allow the "do I support this feature" flags into the parent data, and then I implement static dispatch methods for each concrete type - even though these static dispatch methods then will often be quite similar, but that is solved with traditional LabVIEW modularization and code reuse (like subVIs, typedefs and such). It works well, but I feel I don't get the full benefit of dynamic dispatching. But that is what I'd do in C++... /Steen
  5. I am working on some labview code that I really want to use OOP. I have some classes, ie, motor, relay, potentiometer, etc that I am using and wanted to incorporate in a state machine. I wonder if there are some good examples of this? I found a thread on here discussing it http://lavag.org/topic/13064-object-based-state-machine-pattern/ , but I am not clear if it answers my question. 1. When I try to wire a class into a state machine (while loop with a case structure), I always get a broken wire in the while loop. It says the wire type is different? Am I thinking of this incorrectly. I have a class object I put on the block diagram, i wire it to 'Initialize.Vi' and it breaks (there and on any vi from that class). Thanks,
  6. Hi, I am making a determined effort to migrate a particular application of mine over the fence to OO, but I would like to be "herded" towards using the correct or proper design pattern(s). This application of mine is a TCP Client app that allows the user to connect to one (1) test server as to display test data in various forms (i.e. tabular, time-histories, gauges, etc.) using a single tab control. There can be up to ten (10) such Clients logged in at one time to the same Server. I have read recently that several folks on NI & LAVA forums advise to move away from the tab control and to use sub panels instead. Combine that with this web page's neat UI plugin example, I seem to be getting close to finding the proverbial "light switch" in the dark room, but ... it could be something else .... Some notes: I do have LabVIEW 2012 at my disposal. The test server is written in C++. Down the road a bit we may need to encrypt the XML stream so I may need to put a LabVIEW web service in between the Server and each Client using SSL - if that's a future design bit to note here but not as important as the basic environment or use case of a TCP Client that displays data via several types of displays - which the display types will only grow in the near future as we all have experienced. So adding different displays should be as "easy" as possible. Note: My question was originally posted here, but I was advised to post it here on LAVA for a more experienced architect to respond. Thank you very much in advance !!! CS
  7. This thread is a follow up to the point discussed in another thread. I opened a new thread to avoid polluting the previous thread with a second discussion. The link is http://lavag.org/topic/16669-universal-fgv/?p=103311 and I want to react to a message from JohnMc86: Hi, I get the advantage of working with both DVR and Objects. However I am still very sceptical about the use of the in place structure to read the object directly in the main VI. I see the DVR Based Objects a really safe way to work with class while making sure they are initialized and to avoid data copies. Working with In Place on the main VI theoriticaly gives me the right to remove an initialized object from a reference and replace it with another object from the class or, even worse, a non initialized object. I am really sceptical on the "well coding" of this based on that point and also based on the fact that you are then manipulating an object outside a method. Is it really the best way to go? Would it not be prefearable to write this function in a method (like "Copy Object" where the object in the reference is duplicated and both object and reference are output. Or a "To Object" and "To Reference" Method with some error handling algorithm to make sure the object input of the "To Reference" method has correctly been initiated or is the same instance than the one that has been called from the "To Object" method)? I ma still "new" to the GOO world, so there might be some subtlety I do not see. Cheers
  8. Hey guys, I have been teaching myself labview for the past 2 to 3 years. I know other programming languages like java and PHP so OOP is not entirely new to me. I am running into an issue with actor framework, specifically writing/reading private data of actor instances. I have created a simple project that encapsulate my issue. Basically, I have a main vi called "test" that starts an actor called "Prime". Prime immediately starts another actor called "Secondary". Secondary has a string in its private data member, with proper read/write accessors. I created a message to be able to write to the string in the private data. Prime has a message dequeuer in its private data so that it can communicate with secondary. My whole goal is to have both prime and secondary running simultaneously and have you, with the click of a button, update that string in secondary and have the new string show on the front panel. I have been struggling with this for a few days now. I have posted the zip file for the project below. Please help. Actor Message Learning.zip
  9. As part of my latest debug process, I've been building EXEs with a basic test platform and the necessary support files - hopefully cutting down on places to look for problems in each component. The test platform in each case is a basic UI where I can enqueue messages (start, stop, do something) or receive messages (data, status, errors) plus the control code I want to trace. I've been successful with debugging and building several components (temperature readout and calculations, stage control, voltage measurement), but have hit a wall with building the last (a pair of power supplies). I have changed no settings from build to build. For all components, I can do what I want in the development environment. With most, I can build and get the same expected function. With the power supplies, I can do what I want in dev, However, the build completes without error, but the EXE is broken. I get a "The VI is not executable. The full development..." error. The major difference that I'm able to discern is that the power supply test platform has reentrant VIs (some are inlined). Since I'm using OOP and dynamic dispatch, they're sharing clones. If I put a "diagram disable" box around the top level VI for one of the supplies, the app builds and runs successfully, albeit with only one supply functioning. I've looked on the web and the causes I've been able to find for the error aren't relevant for my test. I'm using an emulator for the supplies (no drivers), I'm not dynamically loading anything (path name failures don't happen), and there are no DLLs (I'm not that good yet). Has anyone else run into problems with this? Why wouldn't the error appear in the build process? I'm running LV2011.
  10. I have just been reading up on topics of OOP in general and although I've used things similar to Interfaces and Abstract classes in LabVIEW, I didn't realize I was doing it. Due to differences between different text based OOP languages and LVOOP I was just wondering if I could get some of you to speak to these two concepts, whether they both really pertain to LVOOP, and possibly provide some actual examples (not just vehicle, shape, cookie cutter examples, but something I'd actually use) of when you'd define an interface vs an abstract class? I'm basically just looking for general information to help strengthen my understanding of these concepts, and most, if not all, examples out there are text based. While I can figure them out, it's much more time consuming, still leaves me with some grey area, and my brain tends to understand LabVIEW much better in the first place.
  11. I've started a project as a way of transitioning from task-based to object-oriented programming. So far, I wish I'd put the effort in sooner. OOP solves a lot of problems I spent frustrating hours considering ways to get around. Platitudes aside, I want to make sure I'm making the right choices as I learn, so that the right practices are in place beginning early in the process. I favor a hierarchical architecture similar to what's been discussed in other topics on the board, and an observation I've made as I write is that much of the code falls into two categories: abstraction layers and mediators. There are both general similarities (queues in and out, auto/manual mode, etc.) and functional differences (power supply vs. multimeter vs. stepper motor), which spawned a thought and a series of questions. I'm considering building a class for a parent abstraction layer and/or a class for a parent mediator, then inheriting as needed. What pitfalls or advantages might I have missed? Will I discover as my skills progress that I've imposed a need for work-arounds? Or, if I'm careful to keep the parent classes away from anything application-specific, will it provide a good base to my coding that can be managed by version control?
  12. I still find myself getting stuck in the "old" ways of coding and somewhat have trouble breaking out of them . I have a question regarding getting something like user preferences throughout code. The way I have done it for years is I have some preferences dialog and a functional global that manages the preferences xml or ini file. When the program starts, the FG loads the file, then if the user updates the preferences from the dialog and saves, the new data is set in the FG and written back to the file. Now, anywhere I need to access the preferences throughout my code I can just use a "get" case on my functional global to get these user preferences. I know I am only writing to the FG from one place (the actual dialog when the user modifies it), so I don't need to worry about race conditions and such. Now, with OOP, I would load all this data into a class. But, my question is, what is the best way to get that class everywhere I need it? I am guessing the general response will be, "it depends!". Is the best option to have the classes that need the preferences data have a preferences data member, and then send a "preferences updated" message to all processes that need it? What if I'm launching a new window that needs it; should it be set in the initialization of the class associated with that Window? Just curious what methods others have used. Thanks.
  13. My OOP naivety shows again, but oh well, I'll learn, albeit slowly. I have a "network connection" base class and from it I have some child classes. I want to create a public method to check if a connection is valid. It seems like this is a method that should somehow go in the base class because it will be the same for all classes (check a connection refnum whether it's tcp,udp, etc, and see if it's valid). But, I am not sure how to best accomplish getting the connection refnum which is held in the child class, into the base class. I obviously don't want some sort of public accessor to call to return the refnum to be passed to the base classes method because I don't want the connection refnum available outside the class. But, I was trying to avoid having a "is connection valid" method in every single class also, when it seems a generic method would work fine. Suggestions?
  14. I am flattening an array of classes and loading into an MSSQL database in an XML column. When the XML is returned it is formatted to take up less space. Which means a line of "<Cluster></Cluster>" becomes "<Cluster/>". When returned in this manner I get an error: 1403 LabVIEW: Attempted to read flattened data of a LabVIEW class. The data is corrupt. LabVIEW could not interpret the data as any valid flattened LabVIEW class. Lines that have <Val/> and <Name/> work ok. It is only the custer tag that has the issue. I have attached two xml files...one with <Cluster/> (doesn't work) and the other with <Cluster></Cluster> (works) for reference. I am hoping someone at NI will take a look at this and enter a CAR if necessary because it just seems to be an overlooked item that doesn't happen much. This seems only possible with classes when a child class is empty. I don't think an empty cluster outside a class is possible. The work around is to perform a search and replace of <Cluster/> with <Cluster></Cluster>. Easy, but shouldn't be necessary. Using LabVIEW 2011. BeforeReplace.xml ClusterReplace.xml
  15. Hi all, I'm somewhat new to Labview so excuse any ineptitude that may arise. I have a program that is centered around an array of Devices - they are various different object types that descend from an abstract Device class. I'm trying to make a VI that can call the correct method VI for a given device in this main list (in an object oriented way, of course). So far this has been fine for most VIs, but now I'm trying to make an overridden VI in each class that opens when called, like a dialog box. As of right now, calling the "Display Info.vi" (the VI in question) on a given device opens the Display Info VI from the Device class, which is basically just a blank, unimplemented VI and therefore useless. Are there some settings I need to check to enforce polymorphic behavior on this VI? Thank you for any info you can provide!
  16. Hi all, I've been learning LabView recently and am still having a few issues trying to get OOP (a concept I am already quite familiar with) working the way I want it to. My particular set up has a generic, abstract class called "Device." This is basically a dummy class from which several other classes inherit properties. One of these is specific device info which is represented by different AO Channels in the different subclasses (which I only have two of for now for simplicity's sake). However I can see no easy solution to make a VI that takes an array of devices and outputs an array of these -different- device info channels. The way I had it working was to make an array of subpanels that display a VI that each subclass overrides: DIsplay Info. But this is very clunky and not at all preferable. I also want to do something very similar except with 2D arrays of data in each class (minor question: how can I make an array of tables? As in 2 dimensions would be displayed at a time). Any thoughts on how this should be done? I feel like it shouldn't be as complicated as I'm making it... Thanks for any help!
  17. I have a question relating to inheritance in one of my programs. When at a customer's site we have Ethernet IP available, which will ultimately be what is used for communication between a PLC and our application upon delivery. However, because I don't have ethernet IP available elsewhere, I was hoping to use TCP/IP when in the office and write a simulator to substitue for E-IP when I don't have it available . The issue is, it doesn't really make sense to have TCP/IP and ethernetIP classes both inherit from a same base class (say, communication class) because the ethernet IP drivers don't really have similar functionality to TCP/IP exposed. With ethernet IP, although it uses TCP/IP underneath it, the API is just a polymorphic VI with an input for the address and tag name. You don't need to open anything, or hold a reference to the session etc. I am wondering if there is some way to set up the class structure so I can easily switch out ethernetIP with TCP/IP and vice versa, even if it does not make sense for them to both inherit from the same base class.
  18. EvaluMation, LLC is currently accepting resumes and searching for engineering talent. We are especially interested in candidates with a solid electrical/programming background and a strong work ethic. Experience with National Instruments products is always a plus! Some desirable skill sets include LabVIEW/TestStand Certifications C/C++/Matlab Programming Object Oriented Design Experience Automation/Instrumentation RF Test Experience Interfaces Well With Customers Engineering Degree Security Clearance/Ability to Obtain Clearance This positon is located in sunny Albuquerque,NM and relocation may be available Please email your resumes to me at Matthew.Dubuque@EvaluMation.com Thanks Matthew Dubuque EE/CLA/CTD www.evalumation.com
  19. I am writing a performance-sensitive application which requires the use of a nearest-neighbor lookup. Originally I used a brute-force method, but unfortunately this gets to be very slow as the data size increases . I have a point cloud of ~100k points in 2D, and need around 50k nearest neighbor lookups per second as a minimum performance requirement. As a solution I wrote a kd-tree in .Net and used LabView to call the .Net dll. However, I discovered that each .Net transaction carries with it about a 0.5ms delay. I've tried bunching the data up into groups, but this only helps so much, as I am using an iterative process. Armed with my new-found kd-tree knowledge, I then wrote the kd-tree in LV-OOP, using DVRs for both subtrees and leaf values. However, my LV implementation is still 100x slower than the .Net implementation, and 20x slower than brute force. And this is with just 10k points. I'm fairly new to LV (about 6 months in an academic environment) and I'm fairly sure I've made a massive blunder somewhere, but I don't have any idea what it might be. http://robowiki.net/...d-tree_Tutorial is the tutorial that I used for writing both trees - note that I've only implemented a 1-NN lookup method, so have no need for the priority queue. Just some notes: I found using in-place data structure unbundle-bundle was much faster than using normal unbundle-bundle for all of the read/writes. The tree started out with pure by-value subtrees and data, so was even slower before I changed to DVRs. The lookup uses a queue as a stack, rather than being recursive. Not sure if this is good or bad. The add element uses recursion. Again, not sure if this is good or bad. I've written speed tests for brute force, .Net and LV lookups with names like with test_...... .vi if you want to compare performance. kd_tree Folder.zip Thanks in advance for any help Julian Kent
  20. Hi Background: I'm diving into this "OOP" stuff right now. My background is NOT CS (Computer Science) but instead electronics and aerospace design. Diving into the deep end of the pool, I'm still in that happy ignorant state of "this is fun" right before I'm realizing I can't swim and that I might drown, or that I can probably stay afloat, but I'm not at all sure what direction I need to swim in to get to shore, or to get to friendly shores... you get the picture I'm sure. (That said, I'm very familiar with "standard" LabVIEW, including RT and FPGA, and have worked full time with LabVIEW for over 2.5 years, I have the CLD and CPI certification for LabVIEW. I currently use LabVIEW 2011.) Anyway. I've read white papers and articles (How to Mitigate Hardware Obsolescence in Next-Generation Test Systems, LabVIEW Object-Oriented Programming: The Decisions Behind the Design, LabVIEW Object-Oriented Programming FAQ), watched presentations and seminars (Data Communication in LabVIEW Technical Seminar), read forum posts(Techniques for componentizing code), looked at exercises and examples (Object Oriented Design Patterns Technical Manual and Exercises, Software Engineering with LabVIEW, ) and poured over blogs (Worker pool – a design pattern for parallel task execution in LabVIEW, Unlimited parallelism & concurrency with recursive dataflow, Eyes on VI's) and I still find myself still confused on a lot of "core" things (that may only come with experience?). I certainly don't claim to understand all of the linked material; I'm still toweling off from drinking from that fire-hydrant, but I wanted to show that I have done some studying of the topic and figured that if I put at least some of the links up here, it may even help others like me find good links on this OOP beast. While a lot of this went over my head, I find myself applying and using the term "complecting" and "complect" a lot when thinking about what I want to do and what I don't want to do and for those with time to kill, its a very interesting talk that points out some things regarding "easy" and "simple" that I think is all too commonly forgotten in todays work.. go on.. I'll wait while you watch/listen to it.. you know you want to click it .. go on, its Simple Made Easy its good for you. I'm still in the planning phase, having been blessed with the time to take it slow and do it right (while maintaining some legacy code on the side while I'm incubating this next generation version), so I'm not committed to any particular architecture or method (including OOP). Key is that I (or <we>) will need to support this platform for years while adding new features etc. along the way. So I'm pretty sure that OOP is the right choice.. but how to organize and implement it. Since I can't hope to learn everything in one post here is: MY QUESTION FOR THIS POST: How do you know what to put in a class and where to draw the line, both in terms of having too many things in one class, and having to granular (huge amount of classes for the littlest things)?? Example: I have an instrument. Its a peculiar type of instrument with a little bit of a personality (that changes with firmware). Do I create a giant class called myInstrument and create methods for everything I need to do (and get) from the instrument? Or do I make smaller classes for "configure" and "acquire" and gather them all up in another class? -The instrument communicates over USB or TCP/IP, surely that should be a layer/class of themselves? (class within class). But then we get to things like the "personality" of the instrument: depending on configuration of the instrument, from when I "start" an acquisition to when I can request the data, it could be anywhere from 10 seconds to HOURS. Do I poll the instrument ready flag in a method or outside of the class/object? (inside, yes, right? to protect access to it, or poll it outside, but by using calls to class method?) Do I have methods that other parts of my software can call to "get status" of the instrument? (wouldn't that complect my software un-necessarily since all sorts of places in the code could be structured to depend on the status of the instrument, when in reality all they probably care about is getting updated data at the end with no regards to the status of the instrument at any given time?) So, then, when the instrument does return data, the data needs to go to all these things, like the file logger (plug-in class?) and the graph history display (another class) only on windows systems, but not cRIO/RT systems, update modbus memory maps (plug-in, some systems, not always) and UPC (plug-in, some systems not always) etc. How should this sharing of data be done? Other parts polling methods of the instrument class? instrument private method publishing data to named queues? (this last seems like the right choice to me but is it in the spirit of OOP??) Then (finally), I need to be able to spawn an unknown (at edit time) number of these instruments and I need to be able to run this code on cRIO OR Windows. If I write the instrument class, I think I can spawn copies of it dynamically... should I put the instrument inside of actors (or is the class itself the actor) in the actor framework? Should I use dynamic events to broadcast stops? What about error handling? A class of itself? An actor? what about the complecting that occurs if you do that? (everyone will be calling the error handler from within itself, causing complecting to happen.. what about just having loops push errors and warnings onto a named queue and have a daemon handle it? Can I do that while using OOP? Is the dameon then a class, or is the daemon the architecture and it uses classes inside of it? As evident by my "question" I am a little overwhelmed when it comes to thinking about what a class/object is and what should live "inside" of it, and what should go around it on the outside. Old habit also keeps screaming QSM QSM QSM and "Action Engines" (aka functional globals) over and over since my brain already knows those tools... I THINK maybe the point is that you define classes and make objects but you tie them all together in "normal" structures like QSM's and possibly even "Action Engines"? Thank you for your time, and I hope for some encouragement, clarifying questions, guiding hints and tips or just about any response you care to share with me!
  21. Hi, Next week I am teaching a LVOOP course and my students use TestStand a lot and I expect to get questions regarding the use of LVOOP and TestStand. The things I have heard are: - TestStand does not recognize LVOOP Objects, so the developper has to flatten the Object Reference to string and then pass the string to TestStand, and viceversa, if they get the flattened Object they need to unflatten to string in LabVIEW: http://digital.ni.co...62573A9004C5A07 - Dynamic dispatch is lost Are there any other tips/tricks/myths I should be aware of? Thanks, Fab
  22. Over the past couple years I've tried unit testing in various projects. Sometimes successful, sometimes not. Even on those rare occasions when I've been successful I usually felt like I was going in circles with my tests, trying to figure out how to best build and organize them. Unit testing was more of a brawl than a ballet. Several months ago I picked up what is now my second favorite book recommendation (right after Head First Design Patterns,) a gem called xUnit Test Patterns. If you're doing OOP, understand patterns, and want to improve your ability to deliver good software, this is the book to get. (There's even lots of information on the website if you don't want to purchase the book.) The book is written for xUnit frameworks so it is a natural fit for JKI's VI Tester. There are a few minor things VI Tester currently doesn't let you do, such as inherit from a test class, but 96+% of the book is directly applicable to your Labview projects.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.