Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write unit tests in plain C?

Tags:

I've started to dig into the GLib documentation and discovered that it also offers a unit testing framework.

But how could you do unit tests in a procedural language? Or does it require to program OO in C?

like image 494
helpermethod Avatar asked Feb 26 '10 17:02

helpermethod


People also ask

Can you write unit tests in C?

The most scalable way to write unit tests in C is using a unit testing framework, such as: CppUTest. Unity. Google Test.

How unit tests are written?

A typical unit test contains 3 phases: First, it initializes a small piece of an application it wants to test (also known as the system under test, or SUT), then it applies some stimulus to the system under test (usually by calling a method on it), and finally, it observes the resulting behavior.


2 Answers

Unit testing only requires "cut-planes" or boundaries at which testing can be done. It is quite straightforward to test C functions which do not call other functions, or which call only other functions that are also tested. Some examples of this are functions which perform calculations or logic operations, and are functional in nature. Functional in the sense that the same input always results in the same output. Testing these functions can have a huge benefit, even though it is a small part of what is normally thought of as unit testing.

More sophisticated testing, such as the use of mocks or stubs is also possible, but it is not nearly as easy as it is in more dynamic languages, or even just object oriented languages such as C++. One way to approach this is to use #defines. One example of this is this article, Unit testing OpenGL applications, which shows how to mock out OpenGL calls. This allows you to test that valid sequences of OpenGL calls are made.

Another option is to take advantage of weak symbols. For example, all MPI API functions are weak symbols, so if you define the same symbol in your own application, your implementation overrides the weak implementation in the library. If the symbols in the library weren't weak, you would get duplicate symbol errors at link time. You can then implement what is effectively a mock of the entire MPI C API, which allows you to ensure that calls are matched up properly and that there aren't any extra calls that could cause deadlocks. It is also possible to load the library's weak symbols using dlopen() and dlsym(), and pass the call on if necessary. MPI actually provides the PMPI symbols, which are strong, so it is not necessary to use dlopen() and friends.

You can realize many of the benefits of unit testing for C. It is slightly harder, and it may not be possible to get the same level of coverage you might expect from something written in Ruby or Java, but it's definitely worth doing.

like image 194
mch Avatar answered Oct 24 '22 15:10

mch


At the most basic level, unit tests are just bits of code that execute other bits of code and tell you if they worked as expected.

You could simply make a new console app, with a main() function, that executed a series of test functions. Each test would call a function in your app and return a 0 for success or another value for failure.

I'd give you some example code, but I'm really rusty with C. I'm sure there are some frameworks out there that would make this a little easier too.

like image 20
David Hogue Avatar answered Oct 24 '22 13:10

David Hogue