There actually is not much activity there.
This thread ain't about what's the best C unit test rig. Google says this
one is:
http://cutest.sourceforge.net/
Curiously, JUnit is humongous and full of features, and these C versions are
tiny. All a unit test rig needs to do is enable the Test/Code/Refactor
cycle, so maybe JUnit is big because Java is a superior language. ;-)
What I really wanted was simply for OP to elaborate on the statement -
I'm genuinely interested to know what about Java OP believes is
fundamentally bad.
Richard Heathfield said it best: Java - a language which, in theory, has no
pointers. But many of us have seen the "Java null pointer exception" message
at the bottom of a public
access terminal screen...
So Sun invented Java to fit the marketing pitch "this language is safer than
that horrible C++, which slows your engineers down with lots of bugs".
Defining Java in the negative - removing innocent features from C++ and
adding nothing - simply left Java open to grow a whole new category of bugs.
TDD does not preclude the need for debugging, if only because mere
mortals are as unlikely (on the first try) to code the test correctly
as they are the actual code.
Under TDD, you run all tests after the fewest possible edits. Usually less
than 10 statements, copies, etc. When a test fails unexpectedly, you only
have <10 edits to throw away, before all the tests pass.
You shouldn't even need to inspect the error to make the tests pass again.
With or without TDD, if you discover a bug that tests didn't catch, you must
debug, because you must preserve your investment in all the edits you made
between adding that bug and finding it. So "debug" means run the debugger,
add trace statements, and sleuth out the cause. Then it means fix the bug
without adding more bugs.
So the knob to set here is how proactive you want your tests, to improve the
odds you find your bugs as early as possible. As you write more tests first,
the rate of long-term bugs goes down, and the rate of punitive debugging
goes down.
Teams using TDD overwhelmingly report much less time spent debugging. Some
report they can code for years, and frequently ship product, without ever
activating a debugger.
Legacy situations typically require debugging, to research what's going on.
C is used close to the metal, so a C team using TDD would not expect to
never invoke a debugger. They would, however, report fewer instances of
punitive debugging.
Ian said:
My workaround is to use a C++ framework for the tests. Sounds messy but
works well. I'm sure many C programmers would prefer an all C solution.
Here's a unit test for a C framework (based on Gtk+) using an all-C test
rig:
TEST_NEW (dia_canvas_item_create)
{
DiaCanvasItem *ti1 = NULL;
DiaCanvasItem *ti2 = NULL;
ti1 = dia_canvas_item_create (TYPE_TEST_ITEM, NULL);
TEST (ti1->parent == NULL);
TEST (ti1->canvas == NULL);
TEST (G_OBJECT (ti1)->ref_count == 1);
ti2 = dia_canvas_item_create (TYPE_TEST_ITEM, "parent", ti1, NULL);
TEST (ti2->parent == ti1);
TEST (TEST_ITEM (ti1)->children->data == (gpointer) ti2);
TEST (G_OBJECT (ti1)->ref_count == 1);
TEST (G_OBJECT (ti2)->ref_count == 2);
g_object_unref (ti1);
}
It tests that dia_canvas_item_create() creates a child item, then creates a
parent item with its child pointer set to the child.
Under TDD, if you didn't have that feature yet, you would write such a test
and get the TEST() lines to fail. (Those should generally be called
CHECK().) Then you write code to pass the test. Because you only write such
code to respond to a failing test, the tests touch every feature you need.
Richard said:
...in the past,
you've appeared (to me at least) to be evasive when it comes down to
actual
details of how to /do/ TDD.
Now that you've shown me your source code...
Oh dear. I didn't write CUT. I did prompt Arjan Molenaar to write the
DiaCanvas tests, but he didn't get the "first part".
I humbly submit the following, which I _did_ write, to make up for my
wooliness:
http://flea.sourceforge.net/TDD_in_a_nut_shell.pdf