Skip to content
Snippets Groups Projects
Commit 6d4c0a2e authored by bbartels's avatar bbartels
Browse files

quad: add testing suite

parent 5f65df69
No related branches found
No related tags found
No related merge requests found
example
\ No newline at end of file
example: example.c test.c test.h
gcc -g -o example example.c test.c test.h
clean:
rm example
Basic Testing Suite in C
----
This test suite helps you run tests. It handles the result of every test
whether it be a success, failure, or segfault, and keeps running until
all tests have been executed. It then gives a summary of the test results.
To use, just write your tests using functions that return `int`s to indicate
failure. 1 means failure. 0 means success.
Then in your main function for your tests, pass these functions to the `test()`
function along with a name you want included in the test report.
```c
int main() {
test(test_func, "this test will pass!");
test(another_func, "this one might fail...");
...
```
Then at the end of your main function, call the `test_summary()` function, and
return its return value from your main function.
```c
int main() {
...
return test_summary();
}
```
An `example.c` file is included for reference.
\ No newline at end of file
#include <stdio.h>
#include "test.h"
int test1() {
puts("hi world.");
return 0;
}
int test2() {
return 1;
}
int test3() {
int *bad = NULL;
int x = *bad;
return 0;
}
int main() {
test(test1, "print hello world");
test(test2, "just fail");
test(test3, "survive segfault");
return test_summary();
}
#include "test.h"
static int num_tests = 0;
static struct Test tests[128];
static int longest_test_name = 0;
void test(int (*function)(), char *test_name) {
int test_name_length = strlen(test_name);
if (test_name_length > longest_test_name) {
longest_test_name = test_name_length;
}
pid_t pid = fork();
if (pid == 0) {
// test process
int exit_status = function();
exit(exit_status);
} else {
int status;
waitpid(pid, &status, 0);
struct Test test;
strcpy(test.name, test_name);
if (WIFEXITED(status)) {
int exit_status = WEXITSTATUS(status);
if (exit_status == 0) {
test.failed = 0;
strcpy(test.result_msg, "passed");
} else {
test.failed = 1;
strcpy(test.result_msg, "FAILED");
}
} else if (WIFSIGNALED(status)) {
test.failed = 1;
strcpy(test.result_msg, "ERROR!");
}
tests[num_tests++] = test;
}
}
int test_summary() {
unsigned char at_least_one_test_failed = 0;
int num_failed = 0;
puts("---------------------------------");
puts("Test results:");
puts("");
int i = 0;
for (i = 0; i < num_tests; i += 1) {
printf("#%3d: %-*s (%s)\n", i + 1, longest_test_name, tests[i].name, tests[i].result_msg);
num_failed += tests[i].failed;
at_least_one_test_failed |= tests[i].failed;
}
puts("");
printf("Total: %3d of %-3d tests passed\n", num_tests - num_failed, num_tests);
puts("---------------------------------");
num_tests = 0;
longest_test_name = 0;
return at_least_one_test_failed;
}
#ifndef TEST_H
#define TEST_H
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
struct Test {
char name[64];
char result_msg[32];
unsigned char failed;
};
void test(int (*)(), char *);
int test_summary();
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment