I'm going to be giving a talk to my department next week about unit testing and test-driven development. As part of this, I'm going to show some real-world examples from some code I've written recently, but I'd also like to show some very simple examples that I'll write in the talk.

I've been searching on the web for good examples, but I've been struggling to find any that are particularly applicable to our area of development. Almost all of the software we write is deeply-embedded control systems running on small microcontrollers. There's a lot of C code that is easily applicable to unit testing (I'll be talking about unit testing on the PC rather than on the target itself) as long as you stay clear of the 'bottom' layer: the stuff that talks directly to the microcontroller peripherals. However, most examples I've found tend to be based on string-processing (e.g. the excellent Dive Into Python Roman numerals example) and since we hardly ever use strings this isn't really suitable (about the only library functions our code typically uses are memcpy, memcmp and memset, so something based on strcat or regular expressions isn't quite right).

So, on to the question: please can anyone offer some good examples of functions that I can use to demonstrate unit testing in a live session? A good answer in my (subject to change) opinion would probably be:

  • A function that is simple enough that anyone (even those who only write code occasionally) can understand;
  • A function that doesn't appear pointless (i.e. working out the parity or CRC is probably better than a function that multiplies two numbers together and adds a random constant);
  • A function that is short enough to write in front of a room of people (I may take advantage of Vim's many clipboards to reduce errors...);
  • A function that takes numbers, arrays, pointers or structures as parameters and returns something similar, rather than handling strings;
  • A function that has a simple error (e.g. > rather than >=) that's easy to put in that would still work in most cases but would break with some particular edge case: easy to identify and fix with a unit test.

Any thoughts?

Although it's probably not relevant, the tests themselves will probably be written in C++ using the Google Test Framework: all our headers already have the #ifdef __cplusplus extern "C" { wrapper around them; this has worked well with the tests I've done so far.

  • Taking the "problem" here as coming up with a presentation to sell TDD to management, this seems to me to fit the desired format reasonably well. The OP seems to be requesting existing solutions to this problem. Jan 11, 2016 at 21:06

2 Answers 2


Here's a simple function that's supposed to generate a checksum over len bytes.

int checksum(void *p, int len)
    int accum = 0;
    unsigned char* pp = (unsigned char*)p;
    int i;
    for (i = 0; i <= len; i++)
        accum += *pp++;
    return accum;

It has a fencepost bug: in the for statement, the test should be i < len.

What's fun is, if you apply it to a text string like this...

char *myString = "foo";
int testval = checksum(myString, strlen(myString));

you'll get the "right answer"! That's because the extra byte that was checksummed was the zero string terminator. So you can wind up putting this checksum function into code, and maybe even shipping with it, and never notice a problem - that is, until you start applying it to something other than text strings.

Here's a simple unit test that will flag this bug (most of the time... :-)

void main()
    // Seed the random number generator

    // Fill an array with junk bytes
    char buf[1024];
    int i;
    for (i = 0; i < 1024; i++)
        buf[i] = (char)rand();

    // Put the numbers 0-9 in the first ten bytes
    for (i = 0; i <= 9; i++)
        buf[i] = i;

    // Now, the unit test. The sum of 0 to 9 should
    // be 45. But if buf[10] isn't 0 - which it won't be,
    // 255/256 of the time - this will fail.
    int testval = checksum(buf, 10);
    if (testval == 45)
        printf("Failed! Expected 45, got %d\n", testval);
  • Very good! This is just the kind of answer that I was hoping for: thank you.
    – DrAl
    Jun 1, 2011 at 7:00
  • When you create the buffer you already have rubbish in that chunk of memory, is it really necessary to initialize it with random numbers? Aug 16, 2013 at 14:12
  • @SnakeSanders I would say yes, because you want unit tests to be as deterministic as possible. If the compiler you use happens to put a 0 there on your developer machine and a 10 on your test machine, you'll have a terrible time finding the bug. I do think that making it depend on the time instead of a fixed seed is a bad idea, for the same reason.
    – Andrew
    Apr 27, 2015 at 23:01
  • Relying on non-deterministic behaviors in a unit test is a bad idea. A flaky test will give you headaches sooner or later...
    – sigy
    Oct 24, 2016 at 11:52

What about implementing a sort function like bubble sort? Once you have the sort function working, you can continue with binary search which is just as good for introducing unit testing and TDD.

Sorting and searching depends on comparisons which is easy to get wrong. It also involves swapping pointers around which must be done with care. Both is prone to errors, so feel free to mess up :)

A few more ideas:

  • Unit tests helps a lot when doing refactoring. So once your bubble sort works, you could change it into a more powerful sort like qsort, and the tests should still pass, proving your new sort function works as well.
  • Sorting is easy to test, the result is either sorted, or it is not, which makes it a good candidate.
  • The same for searching; it either exists or it doesn't.
  • Writing tests for sorting opens up discussions like what type of input to use for test (zero elements, random input, duplicate entries, huge arrays etc).
  • Do you have any specific suggestions for a simple error that would show how testing makes life easier?
    – DrAl
    May 26, 2011 at 12:01
  • @DrAl: Updated my answer with that. May 26, 2011 at 12:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.