Added basic test execution collector and runner and some reference assertions

This commit is contained in:
Dmitriy Shishkov 2021-02-15 07:47:13 +05:00
commit 612c64ca21
No known key found for this signature in database
GPG Key ID: 7CAE12ED13853CAC
10 changed files with 231 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
obj/
.vscode
*.so*

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"files.associations": {
"ctest.h": "c",
"typeinfo": "c",
"*.a": "c"
}
}

49
Makefile Normal file
View File

@ -0,0 +1,49 @@
CC=gcc
CFLAGS=-Wall -pedantic -std=c11 -fPIC
LDFLAGS=
DFLAGS=-gdb3
NAMES=ctest funcs
set_values = $(addprefix $(1),$(addsuffix $(2),$(3)))
sourcefy = $(call set_values,./src/,.c,$(1))
objectify = $(call set_values,./obj/,.o,$(1))
SOURCES=$(foreach N,$(NAMES),$(call sourcefy,$(N)))
OBJECTS=$(foreach N,$(NAMES),$(call objectify,$(N)))
all: libctest
libctest: $(OBJECTS) check-env
gcc -shared -Wl,-soname,$(addsuffix .so.$(CT_VERSION),$@) -o $(addsuffix .so.$(CT_VERSION).0,$@) $(OBJECTS)
$(OBJECTS):%.o: $($(call sourcefy $@)) objdir
$(CC) $(CFLAGS) -c -o $@ $(call sourcefy,$(subst .o,,$(@F)))
objdir:
mkdir -p obj
install: check-env
cp libctest.so.$(CT_VERSION).0 /usr/local/lib/
ln -sf /usr/local/lib/libctest.so.$(CT_VERSION).0 /usr/local/lib/libctest.so.$(CT_VERSION)
ln -sf /usr/local/lib/libctest.so.$(CT_VERSION).0 /usr/local/lib/libctest.so
mkdir -p /usr/local/include/ctest
cp $(wildcard ./include/*) /usr/local/include/ctest
uninstall: check-env
rm -f $(wildcard /usr/local/lib/libctest.so*)
rm -rf $(wildcard /usr/local/include/ctest/*)
check-env:
ifndef CT_VERSION
$(error CT_VERSION is undefined)
endif
.PHONY:
clean
clean:
rm -rf obj
rm $(wildcard libctest.so*)

15
README.md Normal file
View File

@ -0,0 +1,15 @@
# Testing library for C
Mostly specialized on unit tests library for improved testing experience
# Example:
```c
#include "ctest.h"
#include "funcs.h"
...
test(is_true(some_function()), "Function is true");
run_tests();
...
```

19
include/ctest.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef CTEST_H
#define CTEST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_structure
{
int result;
char *name;
} test_t;
void run_tests(int *which);
test_t *new_test(int res, char *name);
void free_test(test_t *o_t);
void test(int res, char *name);
#endif

8
include/funcs.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef FUNCS_H
#define FUNCS_H
int is_equal(void *res, void *correct);
int is_true(void *res);
int is_false(void *res);
#endif

BIN
obj/ctest.o Normal file

Binary file not shown.

BIN
obj/funcs.o Normal file

Binary file not shown.

114
src/ctest.c Normal file
View File

@ -0,0 +1,114 @@
#include "../include/ctest.h"
static test_t **tests;
static int tests_k;
/**
* Executes one test check. Fails if NULL passed
* @param test Test to execute
* @param failde_k Counter of failed tests. Link is passed because it is incremented inside function body
* @param n Test number to print
*/
void execute_test(test_t *test, int *failed_k, int n)
{
if (test == NULL)
{
fprintf(stderr, "No such test: %d", n + 1);
exit(EXIT_FAILURE);
}
if (test->result)
fprintf(stdout, "%s\n\033[0;32m%d - Passed\033[0m\n", test->name, n + 1);
else
{
fprintf(stdout, "\033[0;31m%d FAILED\033[0m\n", n + 1);
fprintf(stderr, "Test %d failded", n + 1);
failed_k++;
}
}
/**
* Runs all tests
* Execute after all test declarations.
* @param which Array of numbers of tests to execute ending with -1 or NULL if all tests must be run.
*/
void run_tests(int *which)
{
fprintf(stdout, "Executing tests:\n");
int failed_k = 0;
if (which == NULL)
{
for (int i = 0; i < tests_k; i++)
execute_test(tests[i], &failed_k, i);
}
else
{
int i = 0;
while (which[i] != -1)
{
int j = which[i];
if (j < 0 || j >= tests_k)
{
fprintf(stderr, "No such test: %d", j + 1);
exit(EXIT_FAILURE);
}
execute_test(tests[j], &failed_k, j);
i++;
}
}
if (failed_k > 0)
{
fprintf(stderr, "%d tests failed", failed_k);
exit(EXIT_FAILURE);
}
else
{
fprintf(stdout, "All tests passed");
exit(EXIT_SUCCESS);
}
}
/**
* Creates new test struct
*/
test_t *new_test(int res, char *name)
{
test_t *n_t = (test_t *)malloc(sizeof(test_t));
n_t->name = strdup(name);
n_t->result = res;
return n_t;
}
/**
* Frees memory allocated for test structure
*/
void free_test(test_t *o_t)
{
free(o_t->name);
free(o_t);
}
/**
* Test declarator. Adds specified test to list of tests
* @param res Response of testing function
* @param name Test name
*/
void test(int res, char *name)
{
if (tests == NULL)
{
tests = malloc(0);
tests_k = 0;
}
tests = realloc(tests, (tests_k + 1) * sizeof(test_t *));
tests[tests_k] = new_test(res, name);
tests_k++;
}

16
src/funcs.c Normal file
View File

@ -0,0 +1,16 @@
#include "../include/funcs.h"
int is_equal(void *res, void *correct)
{
return res == correct;
}
int is_true(void *res)
{
return res && 1;
}
int is_false(void *res)
{
return !res;
}