Tutorial

Here are several simple steps to make your tests working.

1. Get CU

  1. Create directory for your tests, say, tests:
    $ mkdir tests && cd tests
  2. Obtain source codes of CU, untar it and compile it:
    $ wget http://cu.danfis.cz/files/cu-0.12.tar.gz
    $ tar xzf cu-0.12.tar.gz
    $ make -C cu-0.12
  3. Rename directory to cu
    $ mv cu-0.12 cu
  4. As last thing, create directory for files containing outputs from testsuites - call this directory regressions:
    $ mkdir regressions

2. Define Tests

Tests will be written in file, say, t1.c:

  1. First include CU macro definitions:
      1   #include "cu/cu.h"
  2. Then test functions can be defined:
      2  #include <stdio.h>
      3  
      4  TEST(test1) {
      5      assertTrue(1);
      6      printf("Hello from test1\n");
      7      assertEquals(1, 1);
      8  }
      9  
     10  TEST(test2) {
     11      assertFalse(0);
     12      assertNotEquals(1, 2);
     13      fprintf(stderr, "Hello from test2\n");
     14  }
     15  
     16  TEST(test3) {
     17      assertFalse(1);
     18  }
    
  3. File t1.c can be downloaded from here.

3. Create Test Suite From Tests

Test functions are organized into test suites:

  1. Create header file t1.h with definition of T1 testsuite consisting of tests from file t1.c.
      1  #include "cu/cu.h"
      2  
      3  // Declarations of tests
      4  TEST(test1);
      5  TEST(test2);
      6  TEST(test3);
      7  
      8  // Collect tests into test suite
      9  TEST_SUITE(T1) {
     10      TEST_ADD(test1),
     11      TEST_ADD(test2),
     12      TEST_ADD(test3),
     13      TEST_SUITE_CLOSURE
     14  };
    
  2. Then C file test.c with main function can be created:
      1  // Include definition of T1 test suite
      2  #include "t1.h"
      3  
      4  // This struct contains all test suites
      5  TEST_SUITES {
      6      TEST_SUITE_ADD(T1), // add T1 test suite
      7      TEST_SUITES_CLOSURE
      8  };
      9  
     10  int main(int argc, char *argv[])
     11  {
     12      // Set up directory where are stored files with outputs from test
     13      // suites
     14      CU_SET_OUT_PREFIX("regressions/");
     15  
     16      // Run all test suites
     17      CU_RUN(argc, argv);
     18  
     19      return 0;
     20  }
    
  3. Files t1.h and test.c can be downloaded from here and here.

4. Compile & Run

Now, everything is prepared and all tests can be compiled, linked and run:

  1. We can use this Makefile (download it from here):
      1  CC ?= gcc
      2  CFLAGS = -g -Wall -pedantic --std=gnu99
      3  LDFLAGS = -Lcu/ -lcu
      4  
      5  OBJS = t1.o test.o
      6  
      7  all: test
      8  
      9  test: $(OBJS)
     10     $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
     11  
     12  %.o: %.c %.h
     13     $(CC) $(CFLAGS) -c -o $@ $<
     14  %.o: %.c
     15     $(CC) $(CFLAGS) -c -o $@ $<
     16  
     17  clean:
     18     rm -f *.o test
     19  
     20  .PHONY: all clean
    
  2. and simply type
    $ make
  3. After compilation, a binary test should emerge. Simply call this binary to run all tests:
    $ ./test
    Output should look like this:
     -> T1 [IN PROGESS]
        --> Running test1...
        --> Running test2...
        --> Running test3...
    t1.c:17 (T1::test3) :: 1 is not false
     -> T1 [DONE]
    
    
    ==================================================
    |               |  failed  |  succeed  |  total  |
    |------------------------------------------------|
    | assertations: |       1  |        4  |      5  |
    | tests:        |       1  |        2  |      3  |
    | tests suites: |       1  |        0  |      1  |
    ==================================================
    

5. Check Regressions

While running tests stdout and stderr are redirected to files. Each test suite has its own files stored in <PREFIX>tmp.<TSNAME>.{out,err} where <PREFIX> is prefix defined using CU_SET_OUT_PREFIX macro and <TSNAME> is name of test suite.

In our case, it means that test suite T1 has its stdout stored in regressions/tmp.T1.out and stderr in regressions/tmp.T1.err. If you look there you will see that tmp.T1.out contains:

Hello from test1

and tmp.T1.err contains:

Hello from test2

Why is it so should be obvious from t1.c source code.


CU provides the python script check-regressions which checks all files generated from test suites for regressions. This script accepts several options, to see them all type:

$ ./cu/check-regressions --help

And back to example.
If you run check-regressions on directory regressions:

$ ./cu/check-regressions regressions

You get this output:

 Processing directory 'regressions/': 
  
 === Can't compare tmp.T1.err T1.err, bacause T1.err does not exist!
 === Can't compare tmp.T1.out T1.out, bacause T1.out does not exist!

This means that script has nothing to compare with. So create some output files:

$ touch regressions/T1.{out,err}

And run check-regressions again:

 Processing directory 'regressions/': 
  
Comparing tmp.T1.err and T1.err  [ FAILED ] 
 --> Diff has 2 lines 
 --> Diff: 
   | 1d0
   | < Hello from test2
Comparing tmp.T1.out and T1.out  [ FAILED ] 
 --> Diff has 2 lines
 --> Diff: 
   | 1d0
   | < Hello from test1

Now, you can see diff between T1.{out,err} files which are taken as base files and newly generated files tmp.T1.{out,err}.
So, fixing this problem is easy:

$ cp regressions/tmp.T1.out regressions/T1.out
$ cp regressions/tmp.T1.err regressions/T1.err

Run check-regressions again:

 Processing directory 'regressions/': 
  
Comparing tmp.T1.err and T1.err  [ OK ]     
Comparing tmp.T1.out and T1.out  [ OK ]

About

CU is simple unit testing framework for handling automated tests in C.

How to use CU see Tutorial.

Source Code

Latest stable release:
cu-0.12.tar.gz.
Git repository: pitweb