470,821 Members | 1,938 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,821 developers. It's quick & easy.

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.
Jun 27 '08 #1
4 1605
12*******@gmail.com wrote:
Hi,

Let's say I have the following class:

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

private:
int* items;
};
I think you oversimplified your example: any implementation off addItem()
will do since whatever it does, no client will be able to tell as the class
does not provide any way of using the private data. Without observable
semantics, neither does the class serve a purpose nor is there anything to
test.

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.
Well, client code will have _some_ uses of the class. Such uses should
provide meaningfull ways of testing the observable behavior of the class,
i.e., you should be able to write tests that make sure the class keeps its
contractual obligations. That is where I would start. Otherwise, you end up
testing implementation details. Since those might change, I don't think
that client or outside test code have any business knowing about them.
[snip]
Best

Kai-Uwe Bux
Jun 27 '08 #2
On Jun 27, 4:15 pm, Joe Greer <jgr...@doubletake.comwrote:
SeanW <sean_woolc...@yahoo.comwrote
innews:59**********************************@l42g20 00hsc.googlegroups.com:
On Jun 27, 8:56 am, Joe Greer <jgr...@doubletake.comwrote:
Greg Herlihy <gre...@mac.comwrote in
news:317895b6-3422-489c-a280-4c502ab5ec62
@a9g2000prl.googlegroups.com:
There should not be any code added to foo's public API
for unit testing purposes.
2. I want the function class to be independent from test class
Yes, the unit test should be completely independent from the
interface being tested (in other words, the unit test should just
be another client of foo - and nothing more).
I wouldn't necessarily disagree with this, but I seem to have a lot
of classes whose primary goal is a side effect. For example a writer
to a file. By design, there really isn't any feedback to the client
of the class, it just works or throws. If I just treat things as a
normal user, I have no way of knowing directly if the data made it to
the file or if there was a error that wasn't reported properly. How
do you usually test such cases or is that another class of test that
isn't called a 'unit test'?
I would just reach around in that case:
test_object.append("some.file", "SOME-STRING");
assert(system("tail -n 1 some.file | grep -q '^SOME-STRING$'") ==
0);
Or something along those lines.
Yes. but that wouldn't be using my class' public interface. I
can see a lot of different ways to check it outside the class,
but is that still within Greg's definition of a unit test?
I don't see why not. The "public" interface of the class is
what is visible from outside the class. Data written a file is
(hopefully) visible, and thus part of the public
interface---part of the post-condition. (I have some cases
where the "post-condition" is a core dump; I also have unit
tests which verify this.)

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #3
James Kanze <ja*********@gmail.comwrote in
news:34**********************************@k30g2000 hse.googlegroups.com:
>
I don't see why not. The "public" interface of the class is
what is visible from outside the class. Data written a file is
(hopefully) visible, and thus part of the public
interface---part of the post-condition. (I have some cases
where the "post-condition" is a core dump; I also have unit
tests which verify this.)

Fair enough, This is what I actually assumed, but I just wanted to be clear
on the definitions in case I was missing something.

joe
Jun 27 '08 #4
On Jun 27, 5:56*am, Joe Greer <jgr...@doubletake.comwrote:
Greg Herlihy <gre...@mac.comwrote in news:317895b6-3422-489c-a280-4c502ab5ec62
@a9g2000prl.googlegroups.com:
There should not be any code added to foo's public API for unit
testing purposes.
2. I want the function class to be independent from test class
Yes, the unit test should be completely independent from the interface
being tested (in other words, the unit test should just be another
client of foo - and nothing more).

I wouldn't necessarily disagree with this, but I seem to have a lot of classes whose primary goal is a side
effect. *For example a writer to a file. *By design, there really isn't any feedback to the client of the
class, it just works or throws. *If I just treat things as a normal user, I have no way of knowing directly
if the data made it to the file or if there was a error that wasn't reported properly. *How do you usually
test such cases or is that another class of test that isn't called a 'unit test'?
Even though the unit test should not call any non-public methods of
the interface being tested - there is no reason why the unit test
should not call other functions, functions that do not belong to the
interface being tested if necessary to verify that a function's
postconditions have been met.

So in this example, the "right" way to verify the interface function
that writes data to a file - would depend (as always) on the exact
guarantee (in the form of postconditions) that the function called,
has made to its clients; (assuming of course the client had first met
all of the function's "preconditions" before the function call).

Therefore, the question is whether the function called, promises to
have written certain information to a file by the time the function
returns. If the function makes such a detailed promise, then the unit
test should indeed open the file (by using standard I/O routines),
read the the file's contents, and verify that they match the content
in the form promised by the interface.

The more likely scenario, however, is that the function being tested
makes a less specific promise, perhaps promising only to store the
user-provided data "in a safe place" (with the implicit promise that
the data stored could be subsequently retrieved intact by the client).
In this case, the unit test should not examine the contents of the
file. In fact, client should not even know that this file exists -
because the interface never promised that the "safe place" was
necessarily in a file. Instead, the unit test has to verify only that
the data has been stored safely enough to be retrievable. So the unit
test would verify the function's postconditions by attempting to
retrieve the data (through the interface's public methods) - and once
the data has been retrieved - comparing it against a copy of the
original data passed to the function call.

Essentially, all unit test verifications will fall roughly into one of
these two categories: either the postconditions will be detailed
enough to be verifiable by external routines - or nonspecific enough
that the public interface will have to offer methods that can be used
for verification. Because, as I noted in my previous post - every time
that a client calls a function, the client "wants" something to happen
(otherwise, why bother?). So one of the primary benefits of writing
unit tests (and the reason why they prove so useful) is that they
reconcile the client's expectations with the implementation's own
guarantees. Otherwise, without a clear accounting on each side, it is
all too easy for the client to make assumptions about an interface
that its implementation never had any intention of guaranteeing. So,
by eliminating discrepancies between what a client expects and what an
implementation delivers - a sizable number of bugs can be avoided.

Greg

Jun 28 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

21 posts views Thread by Jon Slaughter | last post: by
16 posts views Thread by A_PK | last post: by
23 posts views Thread by mark.moore | last post: by
6 posts views Thread by JoeC | last post: by
reply views Thread by mihailmihai484 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.