From: Carlos Moreno on 18 Sep 2006 15:27 Ulrich Eckhardt wrote: >>What I have in mind is debugging/testing (QA kind of >>testing). Having client code (the "test protocol") >>access to private data members gives you more flexibilty >>in terms of easily creating test case scenarios. > > [dangers of various ways of changing private to public] > > Carlos, you could for every class Foo have a friend class > Foo_UnitTest, which requires neither hacks nor changes to > any code. Well, after hearing the suggestion from you and from Alf, yes, it feels like "DUH!" :-) At least the question did trigger an interesting discussion (with little practical value, at least with respect to my original intent, but still interesting) Cheers, Carlos -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Dave Steffen on 18 Sep 2006 16:59 "Jiang" <goo.mail01(a)yahoo.com> writes: > Ulrich Eckhardt wrote: > > Carlos Moreno wrote: > > > What I have in mind is debugging/testing (QA kind of > > > testing). Having client code (the "test protocol") > > > access to private data members gives you more flexibilty > > > in terms of easily creating test case scenarios. > > [dangers of various ways of changing private to public] > > > > Carlos, you could for every class Foo have a friend class > > Foo_UnitTest, which requires neither hacks nor changes to > > any code. > > > > Well, since we can not add friend class Foo_UnitTest without > touch the class Foo, the above method is quite expensive, isn't it? > Also it is possible that someone will use the class Foo_UnitTest > for other purposes. > > BTW I really do not see why the replacement is necessary. > > 1. For debugging: > > Since the debugger is part of the implementation, the access > control should not be an issue. All the unspecified behaviors > will become perfectly well-defined behaviors, provided we > stay with the same compiler/debugger. > > 2. For unit testing: > > Also I do not see the benefits for unit testing while all the objects > will be teared up. All we need to test are the public interfaces > and internal state probing will introduce unnecessary > dependencies between the test-cases and classes. > Logger/analyzer utilities can be used if the internal states are > really necessary. (I started a thread on this topic recently on Boost-users.) The situation I have is a class, with a public interface; but the heavy lifting is done by private methods, that implement some extremely non-trivial mathematics. 1) If the public interface is something that's hard to fake up for unit testing (i.e. involves BigHonkinHairyClasses, to coin a phrase from Scott Meyers), the cost of hooking up and maintaining a unit test that talks to the public interface may be prohibitive. (Alas, our code base has this problem in spades.) 2) Unit tests of the public interface don't do a good job of pinpointing math errors; an incorrect answer out of the public interface could result from a mistake anywhere in the math code. Therefore, it's much preferable to unit test the private methods directly. 3) It's much, much easier to test corner cases of mathematical algorithms directly, as opposed to trying to come up with a BigHonkinHairyClass object with just the right internal state to poke at a math algorithm in a particular way. (2 and 3 really amount to a desire to do "white box"-ish unit tests.) Responses on the Boost Users list included to: A) Do the "friend class Tester" thing, as Ulrich Eckhardt said above. Involves adding a friend declaration to classes, which may not be possible. Also has problems under some circumstances (pimpl idioms...) B) Do the "#define private public" thing as discussed in this thread. Evil, but carefully contained, fed, and taken-for-a-walk- twice-daily evil. :-) C) Do the "Inherit from the class and change the visibility, and/or add interface to make the class' guts available for testing" thing, proposed by Jason Aubrey. Requires using "protected" instead of "private", which has other implications, and may not be possible. D) Break the complex mathematical innards out into a separate class, that exposes them for use. (I think David Abrahams advocated this approach.) Personally, I think A frequently works, and isn't too ugly to live with. D is a nice ideal, and I'll go there if I can. Given the code base I'm already working with, that kind of redesign will seldom be practical (alas). Alas, B is evil, but it's the only idea I've gome up with, or heard from anybody else, that allows unit tests access to class' innards, with _no_ change to class design or implementation. ---------------------------------------------------------------------- Dave Steffen, Ph.D. Software Engineer IV Disobey this command! Numerica Corporation - Douglas Hofstadter dgsteffen at numerica dot us [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Carlos Moreno on 18 Sep 2006 18:22 { I apologize if mistaken / too sensitive (being a fairly new moderator for clc++m), but there seems to be an (off-) topic drift here, towards general language-independent sofware testing techniques. Please keep this related to C++ in follow-ups. -mod/aps } Jiang wrote: > 2. For unit testing: > > Also I do not see the benefits for unit testing while all the objects > will be teared up. All we need to test are the public interfaces > and internal state probing will introduce unnecessary > dependencies between the test-cases and classes. > Logger/analyzer utilities can be used if the internal states are > really necessary. > > Or, I missed something important for testing? See my reply to Andrei Polushin earlier in this thread for an argument -- I'm not saying or suggesting that you're mistaken; simply that in that post, I gave some arguments in favor of testing more than just the public interfaces. Carlos -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Andrei Polushin on 20 Sep 2006 11:30 Dave Steffen wrote: > Alas, "#define private public" is evil, but it's the only idea I've > come up with, or heard from anybody else, that allows unit tests > access to class' innards, with _no_ change to class design or > implementation. For legacy code, it could be useful to inject several calls to logger object at some control points of that code, then examine the results gathered by logger in your test. Such technique requires no changes in design, no hacking, and isolates tester from implementation details. -- Andrei Polushin [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Pages: 1 2 3 4 5 Prev: Callback-related libraries and terminology Next: fgets() vs std::getline() performance |