tags:

views:

1867

answers:

7
+5  Q: 

How to test C Code

How do you perfom Unit-Test like tests in C? Which framework or do you do other Tests as Unit-Tests on code level?

+7  A: 

Check is a good test framework for C.

Mark Biek
A: 

Google has lots of ideas for unit-testing C

chessguy
I didn't give the negative vote, but I'm tempted. You could be referring to the main Google search (which would be an answer to many of the questions posted here) or to some of the Google Code projects, in which case you could provide value by pointing out which. You're not wrong; just unhelpful.
Jonathan Leffler
+2  A: 

XCode on Mac has something they called CPTest kind of built-in. I made a portable version that I posted here

http://www.loufranco.com/blog/files/AppleCppUnitPort.html

I was targeting gcc on Windows, but I imagine it would work elsewhere, and it's a very simple framework if you want to see how to implement such a thing.

Lou Franco
A: 

You can find information on a number of C unit test frameworks at www.xprogramming.com, in particular at the software link.

Jonathan Leffler
A: 

You may want to have a look at cfix -- it is a unit testing framework specialized for Win32 platforms and NT kernel mode. Supports both C and C++.

Johannes Passing
A: 

If you're using Windows as your dev environment, CUnitWin32 might serve your purpose

Dushara
+3  A: 

Personally I like the Google Test framework.

The real difficulty in testing C code is breaking the dependencies on external modules so you can isolate code in units. This can be especially problematic when you are trying to get tests around legacy code. In this case I often find myself using the linker to use stubs functions in tests.

This is what people are referring to when they talk about "seams". In C your only option really is to use the pre-processor or the linker to mock out your dependencies.

A typical test suite in one of my C projects might look like this:

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

Note that you are actually including the C file and not the header file. This gives the advantage of access to all the static data members. Here I mock out my logger (which might be in logger.o and give an empty implementation. This means that the test file compiles and links independently from the rest of the code base and executes in isolation.

As for cross-compiling the code, for this to work you need good facilities on the target. I have done this with googletest cross compiled to Linux on a PowerPC architecture. This makes sense because there you have a full shell and os to gather your results. For less rich environments (which I classify as anything without a full OS) you should just build and run on the host. You should do this anyway so you can run the tests automatically as part of the build.

I find testing C++ code is generally much easier due to the fact that OO code is in general much less coupled than procedural (of course this depends a lot on coding style). Also in C++ you can use tricks like dependency injection and method overriding to get seams into code that is otherwise encapsulated.

Michael Feathers has an excellent book about testing legacy code. In one chapter he covers techniques for dealing with non-OO code which I highly recommend.

Edit: I've written a blog post about unit testing procedural code, with source available on GitHub.

mikelong