https://github.com/izenynn/mini-unit
A simple unit test framework for C and ASM in C.
https://github.com/izenynn/mini-unit
asm c linux macos test-framework unit-testing unit-testing-framework unit-testing-library unittest unittest-framework unittesting unittesting-library unittests
Last synced: about 2 months ago
JSON representation
A simple unit test framework for C and ASM in C.
- Host: GitHub
- URL: https://github.com/izenynn/mini-unit
- Owner: izenynn
- Created: 2023-05-10T08:38:15.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-16T10:55:03.000Z (9 months ago)
- Last Synced: 2025-01-22T05:15:30.122Z (3 months ago)
- Topics: asm, c, linux, macos, test-framework, unit-testing, unit-testing-framework, unit-testing-library, unittest, unittest-framework, unittesting, unittesting-library, unittests
- Language: Makefile
- Homepage:
- Size: 26.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# mini-unit
## Contents
- [Info](#info)
- [Usage](#usage)
- [Automatic tests execution](#automatic-tests-execution)
- [With the provided Makefile](#with-the-provided-makefile)
- [An example of a custom Makefile](#an-example-of-a-custom-makefile)
- [Other](#other)## Info
A simple unit test framework for C and ASM in C.
*Written in just one small .h! :D*
## Usage
This project aims to keep unit testing simple, so its pretty easy to use.
First, create a test `.c` file, for unit testing I don't like to have the test files in a `tests/` directory, I prefer to put them next to the respective `.c` so I have both files at hand easily.
Usually a name it `*_test.c`, so for the `foo.c` file I would create `foo_test.c`.
First include the library:
```c
#include "miniunit.h"
// ... other includes
```
*Note: don't forget to compile with `-I./MINI_UNIT_DIR`*Then, add a `TEST_MAIN` and make sure you call the `END()` macro at the end:
```c
#include "miniunit.h"// END() will output the result and exit with 0 if successful, or 1 if failure,
// you can take advatage of that if you automate the execution of tests
TEST_MAIN {
END();
}
```Now, you can add `TEST_CASE`s and `ASSERT`s inside them, and call them from `TEST_MAIN` using `RUN_TEST`:
```c
#include "miniunit.h"TEST_CASE(foo) {
int bar = 42;
ASSERT(bar == 42, "bar is not 42!");
}TEST_MAIN {
RUN_TEST(foo);
END();
}
```Of course you can scale this all you want, you can call multiple `ASSERT`s in one `TEST_CASE`, do more `TEST_CASE`s, and since this is just C with macros, you can do whatever you want.
Just renember to call the `TEST_CASE`s using `RUN_TEST`, and to call `END()` at the end.
*For a complete usage example, you can check my `libasm` project [here](https://github.com/izenynn/libasm), in which I use `mini-unit` to test the functions of the library.*
## Automatic tests execution
### With the provided Makefile
For unit testing I don't like to have the test files in a `tests/` folder, I prefer to put them next to the respective `.c` so I have both files at hand easily.
If you also like to place your tests with the original file, you can use the provided `Makefile` for automating your tests, just clone this project inside your project directory:
```bash
git clone --recurse-submodules https://github.com/izenynn/mini-unit.git
```And assuming you project structure is as follows:
```
project/
├── ...
├── include/
├── src/
├── Makefile
└── mini-unit/
├── Makefile
└── ...
```add this to your project Makefile:
```makefile
# define the necessary variables# mini-unit location :)
TEST_DIR := mini-unit# your test files
TEST_SRC_FILES := \
ft_strlen_test.c \
ft_strcmp_test.c
# in my case I have them inside a `src/` directory
TEST_SRC := $(addprefix $(SRC_DIR)/, $(TEST_SRC_FILES))
```
```makefile
# create a check rule and make sure you are providing the necessary values:
# - `SRC`: your project src files, in my case it would be something
# like `src/ft_strlen.c src/ft_strcmp.c ...`
#
# - `TEST_SRC`: test sources as showed above
#
# - `RELATIVE_PATH`: the relative path to your project from the 'mini-unit'
# directory location.
#
# this is also used to cut it off from test log output
# so instead of `../src/ft_strlen_test.c` it prints the
# rute relative to the project `src/ft_strlen_test.c`
#
# if you add this to your own Makefile make sure it has the
# correct syntax, check the provided Makefile for details
#
# - `INCLUDES`: mini-unit includes your project path with -I./$(RELATIVE_PATH)
# but if you compile your project with -I./,
# add those paths here separated with spaces.
check:
$(MAKE) -C $(TEST_DIR) SRC='$(SRC)' TEST_SRC='$(TEST_SRC)' RELATIVE_PATH='..' INCLUDES='include'# update your clean rule
clean:
$(MAKE) -C $(TEST_DIR) fclean
# ...
```*To check a working `Makefile`, you can check my `libasm` project `Makefile` [here](https://github.com/izenynn/libasm).*
And that's all, now run `make test` and have fun! :D
### An example of a custom Makefile
If the provided `Makefile` is not an option for your project, you would probably want to add some `test` rule to your project `Makefile`, here is a quick example assuming your test files follow the `*_test.c` naming convention:
```makefile
CC = gcc
CFLAGS = -Wall -Werror -Wextra
SRC = $(wildcard src/*.c)
TEST_SRC = $(wildcard src/*_test.c)
OBJ = $(SRC:.c=.o)
TEST_OBJ = $(TEST_SRC:.c=.o)
TEST_BIN = $(patsubst src/%,tests/%,$(TEST_SRC:.c=.test))all: $(NAME)
# ...
check: $(TEST_BIN)
@total=0; success=0; failure=0; \
for test in $^; do \
./$$test; \
exit_code=$$?; \
if [ $$exit_code -eq 0 ]; then \
success=$$((success+1)); \
else \
failure=$$((failure+1)); \
fi; \
total=$$((total+1)); \
done; \
echo "============================================================"; \
echo "test summary"; \
echo "============================================================"; \
echo "# TOTAL: $$total"; \
echo "# PASS: $$success"; \
echo "# FAIL: $$failure"; \
echo "============================================================";%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@tests/%_test.test: src/%_test.o $(filter-out %_test.o, $(OBJ))
@mkdir -p tests
$(CC) $(CFLAGS) $^ -o $@clean:
rm -f $(OBJ) $(TEST_OBJ)
rm -rf tests.PHONY: all clean test
.SECONDARY: $(TEST_OBJ)
```### Other
This is a pretty simple test framework, is just some `.h` file, there are tons of ways to make it work with your project, so you can just use the `.h` and implement the automatic execution of the tests in a way that fits your project! :D
##
[](https://forthebadge.com)
[](https://forthebadge.com)