Hi,
I am trying to formalize my programming practices in preparation to do it professionally (I have been doing it as a hobby for 18 years). Unfortunately they didn’t really teach us useful stuff in school, so I am trying to learn these things on my own. One aspect that I am trying to learn is unit-testing.
I have read various things about unit-testing, but as a visual learner — who has difficulty reading anything longer than a paragraph :) — I have found nothing useful. I am looking for real examples (I code mostly in VC++, not Java or C# as most of the examples tend to be). Unfortunately most of the information I have seen on unit-testing has been long, verbose prose that vaguely describes what unit-testing is rather than showing some concrete examples (and especially not in C++).
I think that I have already been doing it for quite a while though because some code I’ve written even eight years ago seems to match the descriptions of a unit-test. However I am not really sure.
When I think of a unit-test, I conjure up images of a function that needs to be verified as working as expected, along with a bunch of calls to it with various inputs, where the output is checked against the expected result. The problem is that my “unit-tests” are not automated. Worse, making an automated unit-test would seem to be a cyclical problem since to make a test function that tests another one, would itself require being able to generate the expected results from the inputs, which would then just make it a duplicate of the function to be tested. ?!?! That means that one would have to manually enter inputs and their expected outputs, which does not sound very automated to me.
Here’s a bit of code that I’ve written that I suspect to be an example of a (not automated) unit-test.
//Normalize returns the sign of a number (as -1 or 1), or 0
INT Normalize (INT num) {return num ? abs(num)/num : num;}
UINT Normalize (UINT num) {return num ? 1 : num;}
FLOAT Normalize (FLOAT num) {return num ? abs(num)/num : num;}
/*
// Normalize Unit Test
BOOL a=FALSE, b=FALSE, c=FALSE;
INT d=-56, e=34, f=0;
a = Normalize(d)==-1;
b = Normalize(e)==1;
c = Normalize(f)==0;
BOOL g=FALSE, h=FALSE, i=FALSE;
UINT j=-56, k=34, l=0;
g = Normalize(j)==1;
h = Normalize(k)==1;
i = Normalize(l)==0;
BOOL m=FALSE, n=FALSE, o=FALSE;
FLOAT p=-56.7, q=34.5, r=0;
m = Normalize(p)==-1.0;
n = Normalize(q)==1.0;
o = Normalize(r)==0.0;
ASSERT(a & b & c & g & h & i & m & n & o);
*/
It doesn’t log results or anything fancy, but it seems like a basic unit-test. Is it? It’s a simple and somewhat contrived example, but it’s representative of what I have basically been doing: call the function to be tested with various inputs (including all edge-cases, and one or two mid-range cases), and test whether they give the expected result. Of course this means that I have to go to all the trouble of figuring out what the expected results should be (which may or may not be easy), as well as sufficient inputs to provide complete coverage of the range of inputs, and making sure that I enter them all correctly. And again, automating it seems like a cyclical problem. I’ve tried writing a unit-test for classes as well, but that seems much harder than testing a simple function; and I have not seen any examples of C++ class tests.
I’ve also read about test frameworks, but I can’t really even picture what that would be like.
Thanks for any input.