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
> 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.
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. > 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) .
> 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.
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
> 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.
> 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.
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.
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
James Kanze wrote: > 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.