Skip to content

piratejon/cboilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cboilerplate

About

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).

Usage

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.

Demonstration

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.

License

MIT (see LICENSE in repository root)

Codename

shiny-tyrion (no one actually calls it this but github suggested it to "inspire" me LOL)

About

C autotools and testing boilerplate

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages