Tuesday, December 24, 2013

Smoke and unit tests for C

Take a look at vstr library source code. This is de facto a standard on tests implementation in C without any additional tools like googletest. See below what to do if you do not want to put one more tool to your project but still need tests.
tst_main.c
#include <stdlib.h>

#include "backup_app.h"
#include "tst.h"

int main (int argc, char ** argv) {

    DBHOST = "127.0.0.1";
    DBUSER = "root";
    DBDB = "???";
    DBPORT = 3306;

    return tst();
}


/*---------------------------------------------------
  mocks */

int snmp_log(int priority, const char *format, ...) {
    va_list ap;

    va_start(ap, format);

    if (vfprintf(stderr, format, ap) < 0)
        goto error;

    va_end(ap);
    return 0;


error:
    va_end(ap);
    return 1;
}
One of the tests, tst_cmd_ok.c
#include <stdlib.h>
#include "extern_cmd.h"
#include "tst.h"

int tst() {
    int     ret;
    char   *args[] = {"/bin/ls", "-l", NULL};
    char   *res = mb_cmd_exec(args, NULL);
    ret = (res) ? SUCCESS : FAILED;
    free(res);
    return ret;
}
Makefile
.PHONY: clean

CC=gcc

CFLAGS=-g -Wall -I..
LDFLAGS=-Wl,--unresolved-symbols=ignore-all
HEADERS=$(wildcard ../*.h)
OBJECTS=$(patsubst %.c,%.o,$(wildcard *.c))
TO_TEST_OBJECTS=$(patsubst %.c,%.o,$(wildcard ../*.c))
MAIN_TST_OBJ=tst_main.o
BUILDLIBS=-lmysqlclient_r -lpthread

_TESTS=$(patsubst %.c,%,$(wildcard *.c))
TESTS=$(patsubst tst_main,,$(_TESTS))

all: $(OBJECTS) $(TESTS)

%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $<

$(TESTS): $(TO_TEST_OBJECTS) $(MAIN_TST_OBJ) $(OBJECTS)
    $(CC) $(CFLAGS) $(LDFLAGS) $(patsubst %,%.o,$@) $(TO_TEST_OBJECTS) $(MAIN_TST_OBJ) -o $@ $(BUILDLIBS)

clean:
    rm -f *~ *.o $(TESTS)
Note LDFLAGS=-Wl,--unresolved-symbols=ignore-all
Script to start tests test.sh
#!/bin/sh

for result in `find . -maxdepth 1 -perm /u=x,g=x,o=x -type f -name 'tst_*'`;
do
  $result
  exit_st=$?
  if [ $exit_st -eq 0 ]
  then
    echo $result : ok
  else
    echo $result : failed
  fi
done

No comments:

Post a Comment