TAP (Test Anything Protocol) is a simple protocol to report the result of a testsuite. It was initially designed for test suites of Perl modules, but developers of the Test::Harness modules have seen the potential for a more generic usage of the protocol outside of the Perl ecosystem and libraries are in development for other programming languages.
I'm writing C code and contrary to most programming langages today, there is no library to build test suites in a standard way. Java has JUnit, Perl has Test::Simple
and Test::More
...
Someone has developped libtap, but no one uses it (except FreeBSD developers as advertised on the site). Also, I do not like the library interface because it exports functions such as ok()
or diag()
which could conflict with existing code. So, I wrote my own library that I will publish one day. But that is not the point of this post.
When you have written a program conforming to the TAP, you want tools to analyse the result of the tests. And the main advantage of using a standardized protocol is to be able to use generic tools and avoid to implement/test/debug them yourself. The problem with TAP is that the only tool that is available is prove
and it suffers of a major flaw: it is designed to run only Perl tests.
Here is a simple TAP-compliant C program that outputs the result of a static testsuite:
#include <stdio.h> int main(int argc, char *argv[]) { puts("1..1\nok 1"); return 0; }
And the output:
$ gcc a.c $ ./a.out 1..1 ok 1
When trying to run it with prove
, perl
complains it did not found Perl code:
$ prove a.out a....Unrecognized character \x7F at a.out line 1. a....dubious Test returned status 9 (wstat 2304, 0x900) FAILED--1 test script could be run, alas--no output ever seen
So I wrote the following generic Perl wrapper a.out.t
that just runs a.out
:
# vim:set ft=perl: use strict; use File::Spec; my $exe = File::Spec->rel2abs($0); $exe =~ s/\.t$//; exec $exe $exe or die "$exe: $!";
And now, success is achieved:
$ prove a.out.t a.out....ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.01 cusr + 0.01 csys = 0.02 CPU)