How to use CPPUnit effectively?

H

Hooyoo

How to use CPPUnit effectively?
When I want to use CPPUnit, I always fint it useless and waste my time.
I think that's mainly
because I don't know how to use CPPUnit effectively. So if somebody
here has some experience,
please share it to me.
And also I expect answers to these questions:
1. Should I write test codes for every member function of my class? If
not, which function should be tested?
2. What else should I consider apart from checking parameters and
return value?

Thanks.
 
I

Ian Collins

Hooyoo said:
How to use CPPUnit effectively?
When I want to use CPPUnit, I always fint it useless and waste my time.
I think that's mainly
because I don't know how to use CPPUnit effectively. So if somebody
here has some experience,
please share it to me.

Like any other new piece of software, start with the smallest example
that compiles and runs, say a TestFixture with single test.
And also I expect answers to these questions:
1. Should I write test codes for every member function of my class? If
not, which function should be tested?

Write the tests first and the members will be added as you require them.
2. What else should I consider apart from checking parameters and
return value?
Side effects.
 
P

Phlip

Hooyoo said:
How to use CPPUnit effectively?

Use UnitTest++. It's much leaner and easier to use:

http://unittest-cpp.sourceforge.net/

CppUnit is stuffed with features you won't need, and they often get in the
way of the few you do.
When I want to use CPPUnit, I always fint it useless and waste my time.

Do you still spend a lot of time debugging? Don't you feel _that's_ a little
more useless and wasteful?
I think that's mainly
because I don't know how to use CPPUnit effectively.

You should write tests for each new line (or two) of the code. Never write
new code without a failing test.

If a test fails unexpectedly, use Undo to revert the code back to the last
state where it passed. This simple trick takes care of nearly all debugging.
1. Should I write test codes for every member function of my class? If
not, which function should be tested?

To make the function exist, you need a test. To make its behavior change,
you need another test. And so on.
2. What else should I consider apart from checking parameters and
return value?

Each test case you write, run it first and see if it fails. The test should
fail for the correct reason. Any kind of code could, in theory, pass the
test, so you should then write just enough code to pass. If the code errs,
it should err on the side of simplicity.

Then write another test to force out the error. These tests, together, will
constrain the innards of that function.

The result works as if the test cases all colluded to constrain all the
function's internal lines, though each test case alone is too simple.
 
P

Phlip

Binary said:
The MS VC project in the zipped source makes me disgusting.

I'm sure you already were. However...

The authors are quite proud to support various other compilers, including
those targeting embedded platforms.

Or did you expect the project to ship with no project files of any kind?
Don't get me started about Autoconf and the abattoir of eternal torture that
is the Makefile format(s)...
 
G

Gianni Mariani

Phlip said:
I'm sure you already were. However...

The authors are quite proud to support various other compilers, including
those targeting embedded platforms.

Or did you expect the project to ship with no project files of any kind?
Don't get me started about Autoconf and the abattoir of eternal torture that
is the Makefile format(s)...

HEY - make is beautiful. I use it with MakeXS (I really have to put
that web page back up) but a copy comes with Austria C++.

autoconf on the other hand, well it surprises me just how much it is used.

As for MS project files, they're a disaster as well, if you have a large
number of project files, its very hard to maintain them.
 
N

Noah Roberts

Phlip said:
I'm sure you already were. However...

The authors are quite proud to support various other compilers, including
those targeting embedded platforms.

Or did you expect the project to ship with no project files of any kind?
Don't get me started about Autoconf and the abattoir of eternal torture that
is the Makefile format(s)...

Shrug... at least they work on more than one platform/compiler
combination.
 
R

ralph

Binary said:
The MS VC project in the zipped source makes me disgusting.

That's interesting. I looked at the MS VC project. Then I looked in a
mirror. Seems like the project doesn't have any effect on me.
 
R

ralph

Hooyoo said:
How to use CPPUnit effectively?
When I want to use CPPUnit, I always fint it useless and waste my time.
I think that's mainly
because I don't know how to use CPPUnit effectively. So if somebody
here has some experience,
please share it to me.

This group is about C++. It seems that you don't understand what unit
tests are about. So I'd like to recommend a very good book about unit
testing to you:

Kent Beck: Test Driven Development. By Example. Addison Wesley.

This book isn't about CPPUnit. It isn't even about C++. It uses Java
and JUnit for its examples. But it is very well written and the example
code is very easy to understand.
And also I expect answers to these questions:
1. Should I write test codes for every member function of my class? If
not, which function should be tested?
2. What else should I consider apart from checking parameters and
return value?

You will find the answers to these non-C++-related questions in the
book I recommended.

You're welcome
 
M

Michael

How to use CPPUnit effectively?

There are several schools of thought on this. One is the "Test Driven
Development" school. See Ian's excellent post or the book by the same
name. The idea is you write tests first, and then write code that
passes those tests.

But, of course, it depends on your project. Another school of thought
is the "Legacy Code" school. (See Working Effectively with Legacy Code
by Michael Feathers.) This is more appropriate if you have a large
project that already exists without tests. The key idea there is that
you add tests before changing things, so that you don't break anything,
and add tests when you add new code, so that the new code is
automatically tested. Over time, more and more of the code is tested.

It depends on your use model. If you're writing code only for
yourself, you probably won't need as much. I tend to not write tests
for obvious things (does a + b work), but for things that have a high
chance of being buggy (does my code work to find the last element in
the array? what if the array is empty?). And particularly for things
with complex logic, where I know it's right, but I fear some other
developer will miss the subtlety of all that a given method does, and
will change it in a way that breaks part (but not all) of the behavior.

One of the best uses I've ever seen was in complex database code that
then did some complex business logic processing processing, followed by
complex display to a browser. By isolating the business logic in unit
tests, you could get it right, and if there was a bug, you didn't have
to start up the database and the web server, so tracking down problems
took seconds instead of minutes.

Another really good use is if you ever find a bug. Don't fix the bug.
Instead, write a test that replicates the bug, then fix the code so it
passes the test. That way, you've fixed the bug, and it will stay
fixed forever (i.e., some other programmer won't reintroduce it).

Sadly, the greatest use of unit tests is when you start getting
coverage over part of code, and it may take a while to get there. At
that point you can feel really confident changing code without breaking
things, and you're confident the code works correctly.

Michael
 
R

Roland Pibinger

How to use CPPUnit effectively?
When I want to use CPPUnit, I always fint it useless and waste my time.
I think that's mainly
because I don't know how to use CPPUnit effectively. So if somebody
here has some experience, please share it to me.
And also I expect answers to these questions:
1. Should I write test codes for every member function of my class? If
not, which function should be tested?
2. What else should I consider apart from checking parameters and
return value?

For beginners to C++ Unit Tests the following article may be helpful:
Chuck Allison: The Simplest Automated Unit Test Framework That Could
Possibly Work - http://www.ddj.com/dept/cpp/184401279

Good luck,
Roland Pibinger
 
R

Roland Pibinger

Use UnitTest++. It's much leaner and easier to use:

http://unittest-cpp.sourceforge.net/

CppUnit is stuffed with features you won't need, and they often get in the
way of the few you do.

I guess a good C++ unit test 'framework' is yet to be written. Most of
the available frameworks are cluttered up with macros which IMO is
rather repelling.

Best regards,
Roland Pibinger
 
G

Gianni Mariani

Roland said:
I guess a good C++ unit test 'framework' is yet to be written. Most of
the available frameworks are cluttered up with macros which IMO is
rather repelling.


There are 4 macros in the Austria C++ unit test framework.

They are:

AT_TestArea - define a test area
AT_DefineTest - define a test
AT_RegisterTest - register a test
AT_TCAssert - "Test case assert" which throws a test case exception

I lied, there is another version of AT_DefineTest that takes a little
more tweaking.

So, what's so "repelling" ?

Oh - btw, here is one of the unit tests.. You can define any number of
unit tests in a file and you can link as many files unit test files as
you like into a single executable. It uses the Austria generic factories
so all the unit tests register themselves automatically.

That's about it. WHAT is repelling about that and what would you do
differently ?

#include "at_bw_transform.h"

#include "at_unit_test.h"

using namespace at;

AT_TestArea( ATBWTransform, "BW Transform" );

#include <iostream>

AT_DefineTest( Basic, ATBWTransform, "Basic BW Transform code test" )
{
void Run()
{
std::string test_str = "fun faster fast";

std::vector<char> test_result( test_str.size() );

unsigned i = BWTEncode( test_str.begin(), test_str.end(),
test_result.begin() );

std::cout << "BW( \"" << test_str << "\" ) = (" << i << ") \""
<< std::string( test_result.begin(), test_result.end() ) <<
"\"\n";

std::vector<char> test_decode( test_str.size() );

BWTDecode( i, test_result.begin(), test_result.end(),
test_decode.begin() );

std::cout << "Decode( \"" << std::string( test_result.begin(),
test_result.end() ) << "\" ) (" << i << ") $
<< std::string( test_decode.begin(), test_decode.end() ) <<
"\"\n";

AT_TCAssert( std::string( test_decode.begin(),
test_decode.end() ) == test_str, "BWT decode failed" );
}
};

AT_RegisterTest( Basic, ATBWTransform );
 
R

Roland Pibinger

There are 4 macros in the Austria C++ unit test framework. They are:
AT_TestArea - define a test area
AT_DefineTest - define a test
AT_RegisterTest - register a test
AT_TCAssert - "Test case assert" which throws a test case exception
I lied, there is another version of AT_DefineTest that takes a little
more tweaking.

So, what's so "repelling" ?

I've not been aware of your Austria framework (even though I live in
Austria. BTW, why haven't you named it Italia?). My favorite unit test
'framework' still is the Standard 'assert' (admittedly a macro in most
implementations).

Best wishes,
Roland Pibinger
 
G

Gianni Mariani

Roland Pibinger wrote:
...
I've not been aware of your Austria framework (even though I live in
Austria. BTW, why haven't you named it Italia?). My favorite unit test
'framework' still is the Standard 'assert' (admittedly a macro in most
implementations).

Because it started off as a country that started with "A". The next
project is Borneo. Besides I think the Austrian's are the most fun
people in Europe.

Hmm. AT_TCAssert gives you the line number and file name (and stack
trace if you want) of the failure and allows you to run the rest of the
tests. You get a full report on all the test failures not just the
first one to fail.

Anyhow, if you're happy with assert, more power to you !
 
P

Phlip

Roland said:
I guess a good C++ unit test 'framework' is yet to be written. Most of
the available frameworks are cluttered up with macros which IMO is
rather repelling.

One Noel Llopis once wrote a book on C++ for game programmers. You should
have seen how he twitched when first I showed him my TEST_() macro (based on
the CppUnitLite TEST() macro). Game programmers are known to abuse macros in
false pursuit of efficiency, and I expect his book ranted against them.

And now his UnitTest++ has exactly the same suite of macros.

In a C language, thou shalt write an assertion with a macro. Even the
various published style guides say so. Further, you can generally write a
better assertion than many vaunted soft languages can support.

In C++, use a macro for any of these techniques:

- conditional compilation
- extracting compiler-defined constants (like __LINE__)
- stringerization
- token pasting

You need all of them for a powerful and flexible unit test rig.

People who are repelled by any language technique, without actually
understanding its uses and costs, are not on the path to wisdom.
 
D

Dave Steffen

Hooyoo said:
How to use CPPUnit effectively? When I want to use CPPUnit, I
always fint it useless and waste my time. I think that's mainly
because I don't know how to use CPPUnit effectively. So if somebody
here has some experience, please share it to me.

Our first cut at a home-grown unit test framework was very much like
JUnit / CPPUnit. The amount of extra verbage needed for even the
simplest tests was a major problem.

We moved to Boost's unit test framework about a year ago, and it's
_much_ better. None of this "unit tests are classes that inherit
from..." stuff, each unit test is a free function.

Roland P. won't like it, because it's replete with macros. :) But
the "auto unit test" facility is very handy, and does a very, very
important thing: it makes writing unit tests extremely cheap.

I recommend that you check it out.
 
P

Phlip

Dave said:
We moved to Boost's unit test framework about a year ago, and it's
_much_ better. None of this "unit tests are classes that inherit
from..." stuff, each unit test is a free function.

Fixtures are a unit test Best Practice, so test rigs should enable them.
Both UnitTest++ and my TEST_() enable them without requiring them. Boost's
doesn't. But indeed do check it out; it _is_ Boost, after all!
 
R

Roland Pibinger

We moved to Boost's unit test framework about a year ago, and it's
_much_ better. None of this "unit tests are classes that inherit
from..." stuff, each unit test is a free function.

Roland P. won't like it, because it's replete with macros. :) But
the "auto unit test" facility is very handy, and does a very, very
important thing: it makes writing unit tests extremely cheap.

If you are fond of boosted stuff TUT might interest you (not that I
recommend it). It uses built-in C++ macros (a.k.a. templates) instead
of preprocessor macros: http://tut-framework.sourceforge.net/

Best regards,
Roland Pibinger
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top