cboilerplate allows me to quickly initialize a C project with autotools and testing. It includes a test framework that fills the gap between MinUnit (http://www.jera.com/techinfo/jtns/jtn002.html) and Check (http://check.sf.net).
1. Fork/clone
2. Setup configure.ac:
-
Change the AC_INIT line in configure.ac to have your project name, version, and email.
AC_INIT([example], [0.1], [js AT piratejon DOT com])
-
Provide a unique filename in the src folder on the AC_CONFIG_SRCDIR line
AC_CONFIG_SRCDIR([src/example.c])
3. Configure src:
- In Makefile.am, replace example with your project name everywhere.
- Also in Makefile.am keep libwhatever_la_SOURCES up-to-date with your files ( *.c and *.h)
- Also in Makefile.am keep whatever_SOURCES up-to-date with your source files ( *.c)
4. Set up a test:
- Edit tests/Makefile.am and replace "example" with your project name everywhere
- Create tests/tests_yourprojectname.c like so:
/**
tests.h is required for TEST and ASSERT but you can include arbitrary
headers too. You can include stdlib.h or whatever you want. I haven't
tried using stdin and stdout though; it might mess with the pipes or
something so for now I'm calling it "unsupported".
**/
// #include <stdlib.h>
#include "tests.h"
void sanity_check_zero ( void )
{
ASSERT ( 0 == 0, "Zero failed to be equal to zero." );
}
void sanity_check_one ( void )
{
ASSERT ( 1 == 1, "One failed to be equal to one." );
/**
You can of course put multiple ASSERTs in each test function and it will
terminate on the first failure.
Each ASSERT must have both parameters but I guess the second one could
be "" if you wanted. I haven't tried that yet!
**/
}
void do_tests ( void ) // this function is mandatory
{
/**
TEST takes the name of a test function, which looks like
"void testfunctionname(void)".
Each function called by TEST is run inside a fork(). The failure of one
does not prevent another from running (unless you just blow everything
compeletely up and the machine grinds to a halt!)
**/
TEST ( sanity_check_zero );
TEST ( sanity_check_false );
// Make it a real party and invite as many tests as you want!
}
- You are done setting up at this point!
5. Compile and run:
$ autoreconf -i -f
$ ./configure
$ make check
6. I guess it's a good idea to remove the [remote "origin"] section of .git/config and/or replace it with one that is meaningful for your project.
Here is what happens using the tests/tests_example.c:
$ autoreconf -i -f
$ ./configure
$ make check
...
Parent PID: 28229
tests_example.c:16:sanity_check_false(): One failed to be equal to zero.
PID 28231 exited with status 1
Test force_segfault (28232): terminated by signal 11
4/6 assertions held (66.67%)
FAIL: tests_example
========================================
1 of 1 test failed
Please report to js AT piratejon DOT com
========================================
...
Two intentional failures illustrate the behavior of the test framework when a segfault occurs and when an assert fails. Therefore it is normal and expected to see 4/6 passing when you run this. You may not want or need to keep those when you write your own tests.
MIT (see LICENSE in repository root)
shiny-tyrion (no one actually calls it this but github suggested it to "inspire" me LOL)