mje Posted September 21, 2012 Report Share Posted September 21, 2012 If I declare foo.vi to be a friend of widget.lvclass, does foo.vi get loaded into memory when the widget class library gets loaded? Will I run into problems if foo.vi doesn't exist or can't be found at run-time? I'm trying to write some VIs to test some private methods of a class, but I'd rather not have these test VIs be included with the class, and I definitely don't want the methods in question to be public. My solution was to use community scope to expose the methods for testing while in the IDE, and simply not include the VIs that test the methods in any builds I distribute. Is there a better way of doing this? Quote Link to comment
Aristos Queue Posted September 21, 2012 Report Share Posted September 21, 2012 No, it does not force the load. It is better IMHO to NOT test your private VIs ever. If you cannot test it through your public interface then it cannot happen. Your test suite is more usable for refactoring if you only test public interface. (lots of other arguments to make here but hand is tired... search lava... i think we've discussed this philosophy option before). Quote Link to comment
crelf Posted September 24, 2012 Report Share Posted September 24, 2012 lots of other arguments to make here but hand is tired... You know, if you programmed graphically it wouldn't hurt so much. 1 Quote Link to comment
Jeffrey Habets Posted September 24, 2012 Report Share Posted September 24, 2012 You know, if you programmed graphically it wouldn't hurt so much. Hmmm, you sure.. Especially after a couple of full days of coding LV my hand really hurts. But, to get back on topic.. I agree with AQ that a class is best tested on it's public interface. I can imagine that in some use cases it would be handy to test some of the private parts and for that I think the next best thing is indeed to use community scope and friend VIs or libs. Putting the test VIs in the class can be a real pain, for example when integrating your class in the greater whole. If during integration changes need to be made to the interface of a class member that is used in a test VI, chances are that test VI will be broken, thus your class will and your application too. So your build is broken because of the broken testcode even though all VIs actually used in the application's hierarchy are not. Quote Link to comment
mje Posted September 24, 2012 Author Report Share Posted September 24, 2012 No, it does not force the load. Thanks for the info! With regards to testing the public API, I can't really argue because for the most part I agree this is the best way to go. Putting the test VIs in the class can be a real pain, for example when integrating your class in the greater whole. If during integration changes need to be made to the interface of a class member that is used in a test VI, chances are that test VI will be broken, thus your class will and your application too. So your build is broken because of the broken testcode even though all VIs actually used in the application's hierarchy are not. You hit on an important aspect, but it's not the only one. If testing should be concerned with the public interface and only the public interface-- no matter how low level, if I change something in the private scope it ought to make a change in the public interface if my tests are "well designed". However when something goes wrong, when you get a failed test and need to debug why that test failed, having tests in place to run on the private bits can be really helpful. Making that interface public just so it can be tested likely isn't the answer, no more than moving the tests into the scope of the library so it can access the private bits. Quote Link to comment
shoneill Posted September 24, 2012 Report Share Posted September 24, 2012 You hit on an important aspect, but it's not the only one. If testing should be concerned with the public interface and only the public interface-- no matter how low level, if I change something in the private scope it ought to make a change in the public interface if my tests are "well designed". Only if your encapsulation is bad. I really don't know if I can agree with this statement at all. It seems very non-oop to me. Shane. Quote Link to comment
ShaunR Posted September 24, 2012 Report Share Posted September 24, 2012 (edited) Well. There is white-box, grey-box and black-box testing. Testing the public interfaces is generally black-box (test the exposed functions without knowledge of the internal workings against a spec). Testing individual methods is generally white-box (full factorial testing with detailed understanding of the internal workings of the function). Testing public methods with specially considered test cases, crafted to exercise internal paths within the functions is grey-box (and also requires detailed knowledge of the internal workings). Positive black-box (i.e. test for what it should do) and negative grey-box (i.e test for what it shouldn't do) together will always give you the best test-cases vs coverage than any amount of white-box testing. If you want to write 3 times as much code to test as the original code and have a 95% confidence. Then black+white is the way forward. If you want to write a fraction of the original code in test cases and have a 90% confidence, then black+grey is the way (and you won't need to solve the problem ). Edited September 24, 2012 by ShaunR Quote Link to comment
shoneill Posted September 25, 2012 Report Share Posted September 25, 2012 Well. There is white-box, grey-box and black-box testing. Indeed. I find it weird to expect a private implementation change to be reflected in the public interface and still claim to be encapsulated. Seems a contradiction to me. Saying that wou're going to test the private implementation (via whichever methods are most preferable for any given class) is something completely differen to saying "I'll test the private implementation via the public interface". Quote Link to comment
shoneill Posted September 25, 2012 Report Share Posted September 25, 2012 Hey, if I'm wrong, I'm always willing to learn. The statement I referred to above just seemed not quite right, and I'm not sure at the moment of you guys agree with me or not..... Quote Link to comment
mje Posted September 25, 2012 Author Report Share Posted September 25, 2012 Time is short, but I'm mostly referring to code coverage. If I test a public method, even though I may not see the private methods that the public one calls, those private execution paths are still under test. If I make a change to one of those private methods, change can still be measured through the public methods that use that private method. That difference could be faster execution time, different return values, changes in state, or even a null change-- seeing no difference is often a valid and useful metric... Quote Link to comment
ShaunR Posted September 25, 2012 Report Share Posted September 25, 2012 (edited) Hey, if I'm wrong, I'm always willing to learn. The statement I referred to above just seemed not quite right, and I'm not sure at the moment of you guys agree with me or not..... Well. Consider you have a public function called "Calculate". This function ,amongst others, uses a "Check For Divide By Zero" private function. You can craft a test case that that can be applied to the public function that specifically supplies a calculation that will result (at some point) in a divide by zero. You are using your knowledge of the internal workings of the "Calculate" function to indirectly test the "Check For Divide By Zero" private function. This is "Grey-Box" testing. The major bonus to this approach is that your test case code can be generic (it only has to interface to the "Calculate" function) and just supply different calculations but test multiple paths through the private functions without having to create code for all-and-sundry. You can even do things like put thousands of your calculations in a file and just iterate through them, throwing them at the "Calculate" Function. The test code is not important, the tests data is what requires consideration and each piece of data can be crafted to test a path or target a specific private function within the public function. Time is short, but I'm mostly referring to code coverage. If I test a public method, even though I may not see the private methods that the public one calls, those private execution paths are still under test. If I make a change to one of those private methods, change can still be measured through the public methods that use that private method. That difference could be faster execution time, different return values, changes in state, or even a null change-- seeing no difference is often a valid and useful metric... As an aside. The examples that ship with the SQLite API are, in fact, the test harnesses and provide 99% coverage of the API (not SQLite itself, by the way. that has it's own tests that the authors do). That is why the examples increase when there are new features Edited September 25, 2012 by ShaunR Quote Link to comment
asbo Posted September 25, 2012 Report Share Posted September 25, 2012 As an aside. The examples that ship with the SQLite API are, in fact, the test harnesses and provide 99% coverage of the API (not SQLite itself, by the way. that has it's own tests that the authors do). That is why the examples increase when there are new features This is a great two-birds-one-stone technique for public libraries. The author can prove to themselves that the features works (and easily catch regressions) and the users get to see how the author intended it be used. Quote Link to comment
Aristos Queue Posted September 26, 2012 Report Share Posted September 26, 2012 Time is short, but I'm mostly referring to code coverage. If I test a public method, even though I may not see the private methods that the public one calls, those private execution paths are still under test. If I make a change to one of those private methods, change can still be measured through the public methods that use that private method. That difference could be faster execution time, different return values, changes in state, or even a null change-- seeing no difference is often a valid and useful metric... Indeed. It makes your test bed more useful for refactoring "this shouldn't change functionality" type testing especially. Quote Link to comment
shoneill Posted September 26, 2012 Report Share Posted September 26, 2012 if I change something in the private scope it ought to make a change in the public interface if my tests are "well designed". Regarding this statement: I seem to realise that people are referring to changes in the behaviour of the object exposing the interface under test (Execution time etc.) and not the interface itself. These (for my definition at least) are not changes to the interface. Hence my comments on the original post. It's a pedantic thing but for me changes to the interface (acceptable input range, fuinction definitions etc.) do not equal changes measurable via the interface. But hey, I have zero formal software training so my personal opinions are just that, personal opinions. A statement like: mif I change something in the private scope it ought to make a change which is measurable over the public interfcace if my tests are "well designed". sounds completely different to me. Shane. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.