Saturday, September 1, 2007

Unit Testing of C Libraries

I wasn't happy with any of the exsiting time tracking applications available, so I've been developing my own time tracker. I hacked together the early prototype in Perl and it works quite well. However, to increase the start-up speed and hone my C skills, I've started rewriting portions in C.

Writing unit tests is a good idea in any language. My first attempt was to write unit tests for my new C functions by writing small C programs which used those functions. That was painful to develop and didn't give me all the nice features of Perl tests that I'm accustomed to. Then I remembered something I'd read in the great book Perl Testing. With a bit of Perl code, one can use Perl's testing tools to test C functions. I've compiled my C functions into a library called libtimeline so this Perl code is all I need:

use strict;
use warnings;
use Test::More tests => 1;

use Inline
    C      => 'const char *timeline_default_filename();',
    ENABLE => 'AUTOWRAP',
    LIBS   => '-L/Users/michael/src/clk -ltimeline',
;

is( timeline_default_filename(), '/Users/michael/.clk/timeline' );
# more tests ...

I wrote a wrapper around most of that, so all I do now is something like this:

use strict;
use warnings;
use Test::More tests => 1;
use App::Clk::TestC;

App::Clk::TestC->function('timeline_default_filename');
is( timeline_default_filename(), '/Users/michael/.clk/timeline' );
# more tests ...

When I was first trying to get this working, I kept getting error messages like:

Use of inherited AUTOLOAD for non-method main::timeline_default_filename() is deprecated
Can't locate auto/main/timeline_de.al in @INC

My first error was that I had typed the C function name incorrectly in the prototype. After I corrected that, I got the same error again. This time it was because my prototype had const char *timeline_default_filename(void) but apparently Inline::C doesn't understand void. Once I changed the prototype to const char *timeline_default_filename() it worked fine.

1 comments:

Anonymous said...

You were visited with a remarkable idea