Yukti is a single header testing library for C/C++ projects. It has no 3rd party dependencies and is fully contained within one single header file.
It provides most of the features available in other popular testing library but in a small single header library.
- State testing
- State/scalar value assertion macros
- Continuous data like array, string assertion macros
- YT_EQ_DOUBLE macro for approx matching of values
- Parameterised testing macros
- Floating point parameter with approx matching of values.
- Faking/Mocking external functions
- Macros to fake external functions
- Behaviour modification of faked functions using custom Handler functions
- Interaction testing
- Assert if an external function was called with expected arguments
- Assert if an external function was called with optional arguments
- Assert if an external function was never called
- Reporting
- Report line numbers and source file of failed expectations
- Report list of all the tests which failed
- Tests executables exit with non-zero code if any of its tests fails
- Time taken to run each test
Some test are failing. Shows source file location and summary lists the failing tests | All test are passing. Shows elapsed time for each test. |
---|---|
![]() |
![]() |
Different examples are placed in the example folder.
YT_TEST
& YT_TESTP
macros are used to create a non-parameterised test and a parameterised
test respectively. Tests functions are identified by their name, that is the 2nd argument in these
macros. These tests functions need to be called in the main()
function explicitly. Arguments for
parameterised tests are given when calling them in the main()
, non-parameterised tests do not take
any argument.
Each test function must end with YT_END()
macro. If omitted will result in compilation errors.
Macro name | Purpose |
---|---|
YT_TEST(g, tn) |
Creates a new non-parameterised test tn under group g . Group name is not yet used for any purpose. |
YT_TESTP(g, tn, t1, t2, ...) |
Creates a new parameterised test tn under group g . t1 , t2 etc are types of parameters to be passed to the test. |
YT_END() |
Ends a test function. It must exist at the very end of each test function. |
YT_INIT() |
Initializes yukti test internals. Must be called from main before test functions are run. |
YT_RETURN_WITH_REPORT() |
Returns from main after printing a summary. |
See Parameterised test example
Assertions macros check state expectations from an SUT (System Under Test). These are several of these macros.
Macro name | Validates |
---|---|
YT_EQ_SCALAR(a, b) |
a == b |
YT_NEQ_SCALAR(a, b) |
a != b |
YT_GEQ_SCALAR(a, b) |
a >= b |
YT_LEQ_SCALAR(a, b) |
a <= b |
YT_GRT_SCALAR(a, b) |
a > b |
YT_LES_SCALAR(a, b) |
a < b |
YT_EQ_MEM(a, b, sz) |
First sz bytes in buffers a & b are equal |
YT_NEQ_MEM(a, b, sz) |
First sz bytes in buffers a & b are not equal |
YT_EQ_STRING(a, b) |
String a and b are equal |
YT_NEQ_STRING(a, b) |
String a and b are not equal |
YT_EQ_DOUBLE(a, b, e) |
Approx match a == b. Passes if mod(a - b) <= e |
YT_NEQ_DOUBLE(a, b, e) |
Approx match a != b. Passes if mod(a - b) > e |
See Basic tests example
More complex files work in conjunction with mocked functions. They help in validating interaction between SUT and external functions. They help in determining if these external functions were called in what order and which what parameters.
Macro name | Validates |
---|---|
YT_MUST_CALL_IN_ORDER(f, ...) |
Function f is called with the given arguments at least once in an particular order |
YT_MUST_CALL_IN_ORDER_ATLEAST_TIMES(n, f, ...) |
Function f is called with the given arguments at least n times in an particular order |
YT_MUST_CALL_ANY_ORDER(f, ...) |
Function f is called with the given arguments at least once in no particular order |
YT_MUST_CALL_ANY_ORDER_ATLEAST_TIMES(n, f, ...) |
Function f is called with the given arguments at least n times in no particular order |
YT_MUST_NEVER_CALL(f, ...) |
Function f with the given arguments is never called |
YT_IN_SEQUENCE(n) |
Repeats expectations n number of times. Used to put expectations for a loop. |
See these examples
- printer_fail example
- printer_success example
When unittesting it might be required to provide a fake definitions of external functions. This is where these macros come in. These fake functions also enable the above mentioned interaction validations and one can modify the behaviour of these fake functions in various ways.
Macro name | Validates |
---|---|
YT_DECLARE_FUNC(rt, f, ...) |
Declaration for fake function f which takes any number of arguments returns some non void type rt |
YT_DECLARE_FUNC_VOID(f, ...) |
Declaration for fake function f which takes any number of arguments returns void |
YT_DEFINE_FUNC(rt, f, ...) |
Definition for fake function f previously declared using YT_DECLARE_FUNC . |
YT_DEFINE_FUNC_void(f, ...) |
Definition for fake function f previously declared using YT_DECLARE_FUNC_VOID . |
YT_RESET_MOCK(f) |
Resets internal state of a fake function previously defined using YT_DEFINE_FUNC* . |
See Mocking and faking example
In order to test yukti.h run tests/run_all_tests.sht
. This runs integration tests & examples.
It uses semantic versioning. See https://semver.org/.
Open a GitHub issue or drop a email at arjobmukherjee@gmail.com. I would love to hear your suggestions and feedbacks.