Google Groups Home
Help | Sign in
c++ class design: where to put debug purpose utility class?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 52 - Collapse all   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
123098...@gmail.com  
View profile
 More options Jun 26, 11:01 pm
Newsgroups: comp.object
From: 123098...@gmail.com
Date: Thu, 26 Jun 2008 20:01:51 -0700 (PDT)
Local: Thurs, Jun 26 2008 11:01 pm
Subject: c++ class design: where to put debug purpose utility class?
Hi,

Let's say I have the following class:

class foo {
public:
    foo();
   void addItem(int item);

private:
   int* items;

};

I want to write a unit test program to test foo::addItem(), to do that
the test program needs to know the contents of foo::items.

So I can add one more public function to class foo:
  int* getItems();

But suppose in my case, the client code of class foo does not need
getItems() at all, this function serves only for test in this case.

So I am considering to have a separate class fooTest and this class is
a friend class of class foo so that it has an API to retrieve all
private data of foo.

I believe this works, but I am wondering if there is better solution.
Basically my goals are:
1. I do not want the class to be bloated with a lot of API which only
serve for test purpose
2. I want the function class to be independent from test class

Thanks a lot.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Phlip  
View profile
 More options Jun 27, 10:31 am
Newsgroups: comp.object, comp.lang.c++
From: Phlip <phlip2...@gmail.com>
Date: Fri, 27 Jun 2008 07:31:17 -0700
Local: Fri, Jun 27 2008 10:31 am
Subject: Re: c++ class design: where to put debug purpose utility class?

123098...@gmail.com wrote:
> Let's say I have the following class:

> class foo {
> public:
>     foo();
>    void addItem(int item);

> private:
>    int* items;

> };

> I want to write a unit test program to test foo::addItem(), to do that
> the test program needs to know the contents of foo::items.

"Testing privates" is a FAQ in the unit testing communities.

The best answers is: If you invented your class using Test Driven Development,
then foo would expose enough effects of its private member - slightly more
effects than its production clients need - that tests can indirectly assess the
performance of the private.

This strategy leverages the purpose of privacy - you can migrate int * items to
some other system (such as std::vector<int> items!), without changing any tests.

More below.

> So I can add one more public function to class foo:
>   int* getItems();

> But suppose in my case, the client code of class foo does not need
> getItems() at all, this function serves only for test in this case.

> So I am considering to have a separate class fooTest and this class is
> a friend class of class foo so that it has an API to retrieve all
> private data of foo.

> I believe this works, but I am wondering if there is better solution.
> Basically my goals are:
> 1. I do not want the class to be bloated with a lot of API which only
> serve for test purpose
> 2. I want the function class to be independent from test class

To add unit tests to pre-existing, Read /Working Effectively with Legacy Code/
by Mike Feathers. He will probably not mention the most savage hack possible in C++:

  #define private public

If you cleanly recompile all your modules in that mode (such as modules going
into a special "test mode" binaries folder), you can safely write unit tests
that see any private. Make sure not to put that line above any #include that
pulls in something you can't recompile in that mode, such as a standard library
module.

--
   Phlip


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
S Perryman  
View profile
 More options Jun 27, 12:40 pm
Newsgroups: comp.object
From: S Perryman <q...@q.com>
Date: Fri, 27 Jun 2008 17:40:40 +0100
Local: Fri, Jun 27 2008 12:40 pm
Subject: Re: c++ class design: where to put debug purpose utility class?

The solution in C++ is to use type coercion. The basic concept is to
produce an exact like-for-like representation of the target type, but with
read-only access to the rep.

type FooREP
{

public:

     const int* items() const { return items ; }

private:

     int* items ;

} ;

Foo f ;
FooREP* rep = static_cast<FooREP* >( &f) ;

Now you have access to the internal representation of a Foo.

IMHO the best approach (in terms of increased correctness, testability,
reusability etc) is to define the getItems op, and then define (in terms
of getItems) a 'difference' post-condition for addItems.

The primary reason for this is : having access to the rep is pointless if
you don't know what the rep state is at the begin/end of each op. And
if you do know, then tis better to explicitly state that knowledge in
post/invariant conditions (ie ADT REP conditions) .

If you had prog lang support for Design by Contract, you could make the
REP conditions private too (ie they are hidden from the user) .

Regards,
Steven Perryman


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
H. S. Lahman  
View profile
 More options Jun 27, 1:32 pm
Newsgroups: comp.object
From: "H. S. Lahman" <h...@pathfindermda.com>
Date: Fri, 27 Jun 2008 17:32:29 GMT
Local: Fri, Jun 27 2008 1:32 pm
Subject: Re: c++ class design: where to put debug purpose utility class?
Responding to 1230987za...

> So I am considering to have a separate class fooTest and this class is
> a friend class of class foo so that it has an API to retrieve all
> private data of foo.

This is pretty standard in C++. In fact, test harnesses are the only
thing I would ever use 'friend' for.

--
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
h...@pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development".  Email
i...@pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Kanze  
View profile
 More options Jun 27, 2:54 pm
Newsgroups: comp.object, comp.lang.c++
From: James Kanze <james.ka...@gmail.com>
Date: Fri, 27 Jun 2008 11:54:25 -0700 (PDT)
Local: Fri, Jun 27 2008 2:54 pm
Subject: Re: c++ class design: where to put debug purpose utility class?
On Jun 27, 4:31 pm, Phlip <phlip2...@gmail.com> wrote:

> 123098...@gmail.com wrote:
> > Let's say I have the following class:

    [...]

> "Testing privates" is a FAQ in the unit testing communities.
> The best answers is: If you invented your class using Test
> Driven Development, then foo would expose enough effects of
> its private member - slightly more effects than its production
> clients need - that tests can indirectly assess the
> performance of the private.

Actually, I think that test driven development would have a
slightly negative effect here.  Greg made the real point: a
function has post-conditions.  If you can't see them, then they
don't matter, and so aren't real post-conditions.  And if you
can see them, you verify that they work.

But this concept really comes out of programming by contract,
rather than test driven design (which can easily be used to
avoid specifying the necessary contracts).

--
James Kanze (GABI Software)             email:james.ka...@gmail.com
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel T.  
View profile
 More options Jun 27, 6:36 pm
Newsgroups: comp.object
From: "Daniel T." <danie...@earthlink.net>
Date: Fri, 27 Jun 2008 18:36:32 -0400
Local: Fri, Jun 27 2008 6:36 pm
Subject: Re: c++ class design: where to put debug purpose utility class?

I agree with James Kanze on this. As the class above sits, there is no
reason to test addItem because it need not do anything at all.

Let's try a more realistic example:

class Bar {
public:
   virtual void update() = 0;

};

class foo {
   // implementation is irrelevant.
public:
   void attach(Bar* b);
   void detach(Bar* b);
   void notify();

};

When Foo::notify() is called, all Bars who have been attached to that
foo should have their update() called, while bars that were attached but
then detached should not have their update() called.

The above, of course, is very testable, despite the fact that Foo's
internals are private.

> So I can add one more public function to class foo:
>   int* getItems();

> But suppose in my case, the client code of class foo does not need
> getItems() at all, this function serves only for test in this case.

What external state changes when you add an item to a foo? Something has
to change or the function has no purpose.

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
123098...@gmail.com  
View profile
 More options Jun 28, 9:44 pm
Newsgroups: comp.object
From: 123098...@gmail.com
Date: Sat, 28 Jun 2008 18:44:51 -0700 (PDT)
Local: Sat, Jun 28 2008 9:44 pm
Subject: Re: c++ class design: where to put debug purpose utility class?
On Jun 27, 4:36 pm, "Daniel T." <danie...@earthlink.net> wrote:

Thanks for the replies most of which do clarify some good points about
what is and how to do unit test.

But I think there is a subtle difference to define "unit". I can not
agree with James Kanze more on unit test *when* the unit is a class,
but how about the unit is a function? A class' public function?

I am adapting Test Driven Development, TDD, into my daily programming.
Please bear with me, I am doing-it-before-learning-it. I designed my
class interface, without implementing the API functions, I started
designing my test class to test each API function. It is at this point
my question coming up.

I learned 2 practical ways in this discussion thread, one is to
"#define private public" and the other is as Philp said, it is
perfectly OK in TDD sense to define a slightly bloated API list.

I posted my question on 2 groups, C++ and Object, interestingly
enough, I see folks in C++ group unanimously think "unit" is class
while Object folks provide me more diverse viewpoints.

Thanks a lot.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Phlip  
View profile
 More options Jun 29, 10:10 am
Newsgroups: comp.object, comp.lang.c++
From: "Phlip" <phlip2...@gmail.com>
Date: Sun, 29 Jun 2008 07:10:21 -0700
Local: Sun, Jun 29 2008 10:10 am
Subject: Re: c++ class design: where to put debug purpose utility class?

1230987za wrote:
> But I think there is a subtle difference to define "unit". I can not
> agree with James Kanze more on unit test *when* the unit is a class,
> but how about the unit is a function? A class' public function?

> I am adapting Test Driven Development, TDD, into my daily programming.

Kanze is a classically-trained "unit tester". In some circles "unit" is a QA
concept - specifically, if a test fails, you only need to inspect one unit.

So "units" are "things which are clearly delimited and accessible to
inspection". That should map onto C++ classes - specifically due to
overlapping requirements. C++ classes _should_ be "things which are clearly
delimited and accessible to inspection". Yet sometimes, by necessity, the
"unit" is a translation unit, or a header, or a peculiar include file, or a
global constant.

Under TDD, if a test fails during development, you only need to inspect (or
revert) the most recent edit. So Developer Tests and Unit Tests have
overlapping abilities and motivations. Many TDD tests will also allow you to
isolate faults to a small unit.

> Please bear with me, I am doing-it-before-learning-it. I designed my
> class interface, without implementing the API functions, I started
> designing my test class to test each API function. It is at this point
> my question coming up.

That's not really TDD. You start at the test, and write each test case to
illustrate one aspect of your target class. Only after you get the test to
tell you what to add to the class, next, do you add it. So imagine if your
method .activate() did not exist yet:

  test_case
     Foo aFoo
     result = aFoo.activate
     assert result == 42

The first time you run that, if activate does not exist yet, you add it.
Then you run it again, and "discover" that activate has no return value. The
third time, you run it and discover the return value is wrong. Only after
this rigorous review of the circumstances - to determine the test is failing
for the correct reason - do you put the actual logic inside the method.

You repeat this aggressive testing, in small cycles (and integrating between
each tiny twitch) to grow an interface.

> I posted my question on 2 groups, C++ and Object, interestingly
> enough, I see folks in C++ group unanimously think "unit" is class
> while Object folks provide me more diverse viewpoints.

"Class" is good for "Unit". But sometimes the Unit is one isolated group of
switches, between microscopic test pads, deep inside a big integrated
circuit.

--
  Phlip
  http://assert2.rubyforge.org/


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Kanze  
View profile
 More options Jun 29, 11:35 am
Newsgroups: comp.object, comp.lang.c++
From: James Kanze <james.ka...@gmail.com>
Date: Sun, 29 Jun 2008 08:35:49 -0700 (PDT)
Local: Sun, Jun 29 2008 11:35 am
Subject: Re: c++ class design: where to put debug purpose utility class?
On Jun 29, 4:10 pm, "Phlip" <phlip2...@gmail.com> wrote:

> 1230987za wrote:
> > But I think there is a subtle difference to define "unit". I
> > can not agree with James Kanze more on unit test *when* the
> > unit is a class, but how about the unit is a function? A
> > class' public function?
> > I am adapting Test Driven Development, TDD, into my daily
> > programming.
> Kanze is a classically-trained "unit tester". In some circles
> "unit" is a QA concept - specifically, if a test fails, you
> only need to inspect one unit.

You mean I'm using a word in its standardly accepted meaning.
(Unit tests have been a required part of development for many,
many years now.)

> So "units" are "things which are clearly delimited and
> accessible to inspection".

That's more or less a definition of "unit", yes.  In practice,
units are units---they're more or less the lowest level in a
hierarchial development.

> That should map onto C++ classes -

Why?  That's the first time I've heard that.  (There are a lot
of cases where they do map onto C++ classes.)

> specifically due to overlapping requirements. C++ classes
> _should_ be "things which are clearly delimited and accessible
> to inspection". Yet sometimes, by necessity, the "unit" is a
> translation unit, or a header, or a peculiar include file, or
> a global constant.

As a minimum, a "unit" is never less than a translation unit,
since current technology doesn't allow you to break things down
any finer.  (Of course, a translation unit is often less than a
complete class.)

> Under TDD, if a test fails during development, you only need
> to inspect (or revert) the most recent edit.

I'm sorry, but that's bullshit.  Regardless of the design
philosophy, if you have halfway decent unit tests, there is a
high probability that the error is somehow due to the most
recent edit.  And regardless of the design philosophy, there's
always a small chance that something in the recent change has
triggered an error which was already there before.  (That's one
of the meanings of undefined behavior---and TDD doesn't remove
undefined behavior from the language.)

> So Developer Tests and Unit Tests have overlapping abilities
> and motivations. Many TDD tests will also allow you to isolate
> faults to a small unit.

All unit tests allow you to more or less isolate faults to a
small unit.  None are perfect, however.

> > Please bear with me, I am doing-it-before-learning-it. I
> > designed my class interface, without implementing the API
> > functions, I started designing my test class to test each
> > API function. It is at this point my question coming up.
> That's not really TDD. You start at the test, and write each
> test case to illustrate one aspect of your target class.

Which, of course, isn't true, because until you have at least
some idea as to what the class is to do, you can't write the
tests.  You start by determining what the class is to do (in
most cases, that means some high level design).  You don't start
by just typing in code, whether it is a test or anything else.

(I find it very hard to conceive that in this day and age,
people are still suggesting that we code before we think.  And
proposing it as a silver bullet, no less.)

--
James Kanze (GABI Software)             email:james.ka...@gmail.com
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bo Persson  
View profile
 More options Jun 29, 1:17 pm
Newsgroups: comp.object, comp.lang.c++
From: "Bo Persson" <b...@gmb.dk>
Date: Sun, 29 Jun 2008 19:17:40 +0200
Local: Sun, Jun 29 2008 1:17 pm
Subject: Re: c++ class design: where to put debug purpose utility class?

Some people do, actually.  :-)

However it depends on how religious you are, and how strictly you want
to follow the dogmas.

If you just want to be able to say that you do TDD, you can start out
with the single test case

assert(false);

This will surely fail, and you are then free to start coding your
design. Just remember to compiler often, and make sure that the test
still fails!

Eventually, you will "discover" that the fault is not in your code,
but in the test case. Then it is time to "refine" the tests. If you
just don't call them unit tests, but use cases, you're done.

Instant TDD(tm).

Bo Persson


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Daniel T.  
View profile
 More options Jun 29, 2:34 pm
Newsgroups: comp.object
From: "Daniel T." <danie...@earthlink.net>
Date: Sun, 29 Jun 2008 14:34:39 -0400
Local: Sun, Jun 29 2008 2:34 pm
Subject: Re: c++ class design: where to put debug purpose utility class?