Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » ObjectGoto page 1, 2, 3, 4, 5, 6  Next

c++ class design: where to put debug purpose utility class?

 
Jump to:  
 
Guest
PostPosted: Fri Jun 27, 2008 3:01 am    Post 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.
 

 
Phlip
PostPosted: Fri Jun 27, 2008 12:31 pm    Post subject: Re: c++ class design: where to put debug purpose utility cl
       
1230987za@gmail.com wrote:

Quote:
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.

Quote:
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
 

 
S Perryman
PostPosted: Fri Jun 27, 2008 2:40 pm    Post subject: Re: c++ class design: where to put debug purpose utility cl
       
1230987za@gmail.com wrote:

Quote:
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

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
 

 
H. S. Lahman
PostPosted: Fri Jun 27, 2008 3:32 pm    Post subject: Re: c++ class design: where to put debug purpose utility cl
       
Responding to 1230987za...

Quote:
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
hsl@pathfindermda.com
Pathfinder Solutions
LINK
blog: LINK
"Model-Based Translation: The Next Step in Agile Development". Email
info@pathfindermda.com for your copy.
Pathfinder is hiring:
LINK
(888)OOA-PATH
 

 
James Kanze
PostPosted: Fri Jun 27, 2008 6:54 pm    Post subject: Re: c++ class design: where to put debug purpose utility cla
       
On Jun 27, 4:31 pm, Phlip <phlip2...@gmail.com> wrote:
Quote:
123098...@gmail.com wrote:
Let's say I have the following class:

[...]
Quote:
"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.kanze@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
 

 
Daniel T.
PostPosted: Fri Jun 27, 2008 8:36 pm    Post subject: Re: c++ class design: where to put debug purpose utility cl
       
1230987za@gmail.com wrote:

Quote:
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.

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.

Quote:
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.
 

 
Guest
PostPosted: Sun Jun 29, 2008 1:44 am    Post subject: Re: c++ class design: where to put debug purpose utility cla
       
On Jun 27, 4:36 pm, "Daniel T." <danie...@earthlink.net> wrote:
Quote:
123098...@gmail.com wrote:
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.

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.

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.
 

 
Phlip
PostPosted: Sun Jun 29, 2008 12:10 pm    Post subject: Re: c++ class design: where to put debug purpose utility cla
       
1230987za wrote:

Quote:
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.

Quote:
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.

Quote:
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
LINK
 

 
Bo Persson
PostPosted: Sun Jun 29, 2008 3:17 pm    Post subject: Re: c++ class design: where to put debug purpose utility cla
       
James Kanze wrote:
Quote:
On Jun 29, 4:10 pm, "Phlip" <phlip2...@gmail.com> wrote:

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.

[...]
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.)

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
 

 
James Kanze
PostPosted: Sun Jun 29, 2008 3:35 pm    Post subject: Re: c++ class design: where to put debug purpose utility cla
       
On Jun 29, 4:10 pm, "Phlip" <phlip2...@gmail.com> wrote:
Quote:
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.)

Quote:
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.

Quote:
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.)

Quote:
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.)

Quote:
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.)

Quote:
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.

Quote:
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.kanze@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
 

Page 1 of 6 .:. Goto page 1, 2, 3, 4, 5, 6  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

Ogrody zimowe, czyszczenie karnisze Płyta ognioodporna poker online zdjęcia ślubne