A Simple and Light C++23 modules based C++ testing library.
import jowi.test_lib;
namespace test_lib = jowi::test_lib;
#include <jowi/test_lib.hpp>
JOWI_ADD_TEST(some_name) {
/*
Do something over here
*/
}
The above will add the test into the test list. Compiling this file using cmake with jowi_add_test
will result in the test being added and run automatically.
JOWI_ADD_TEST(test_name)
This macro creates a function that will add a function declared after it into the test set. An example of adding a test is as follows :
import jowi.test_lib;
#include <jowi/test_lib.hpp>
JOWI_ADD_TEST(your_test_name) {}
-
JOWI_SETUP(argc, argv)
This macro setups a function that will setup the test settings for a specific use case. Treat this as if it is a constructor that will construct the tests. -
JOWI_TEARDOWN()
This macro is run at the end of a successful test. Treat this as if it is a destructor that will destruct tests.
All variables that modify a test can be modified through its global context which is a structure declaration pertaining to the following :
struct test_context {
int thread_count = 1;
test_suite tests = test_suite{};
test_time_unit time_unit = test_time_unit::MICRO_SECONDS;
}
To obtain the global context, call jowi::test_lib::get_test_context()
, this will return a reference to the test context.
test_context& get_test_context();
This sets the time unit used when logging the tests. Valid values are:
enum struct test_time_unit { MICRO_SECONDS, MILLI_SECONDS, SECONDS };
Sets the amount of threads to use when running tests. The default value is 1, and if you desire single threaded execution, there is no need to add a new thread.
This documentation covers all assertion functions in the jowi::test_lib
module. All functions throw a fail_assertion
exception when the assertion fails, which can be caught by a test framework to mark a test as failed or to ignore an error.
Checks that two values are equal using the ==
operator.
Example:
assert_equal(42, 42); // Passes
assert_equal("hello", "hello"); // Passes
assert_equal(3.14, 2.71); // Throws fail_assertion
Checks that two values are not equal using the ==
operator.
Example:
assert_not_equal(42, 24); // Passes
assert_not_equal("foo", "bar"); // Passes
assert_not_equal(5, 5); // Throws fail_assertion
Checks that the first value is less than the second value using the <
operator.
Example:
assert_lt(5, 10); // Passes
assert_lt(1.5, 2.0); // Passes
assert_lt(10, 5); // Throws fail_assertion
assert_lt(5, 5); // Throws fail_assertion (equal values)
Checks that the given boolean expression evaluates to true.
Example:
assert_true(5 > 3); // Passes
assert_true(true); // Passes
assert_true(false); // Throws fail_assertion
assert_true(x > 0, "x must be positive"); // Custom error message
Checks that the given boolean expression evaluates to false.
Example:
assert_false(5 < 3); // Passes
assert_false(false); // Passes
assert_false(true); // Throws fail_assertion
assert_false(x < 0, "x should not be negative"); // Custom error message
Checks that two floating-point numbers are close within a specified tolerance. The second overload works with any floating-point type and uses RMS difference for comparison.
Example:
// First overload (double)
assert_close(3.14159, 3.14160); // Passes (within default tolerance)
assert_close(1.0, 1.1, 0.2); // Passes (within custom tolerance)
assert_close(1.0, 2.0); // Throws fail_assertion
// Second overload (generic floating-point)
assert_close(3.14f, 3.141f, 0.01f); // Passes with float
assert_close(1.0L, 1.00001L, 1e-4L); // Passes with long double
Checks that two ranges contain equal elements by comparing each corresponding pair.
Example:
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {1, 2, 3};
std::array<int, 3> arr = {1, 2, 3};
assert_equal(v1, v2); // Passes
assert_equal(v1, arr); // Passes
assert_equal(v1, {1, 2, 4}); // Throws fail_assertion at index 2
Checks that two ranges contain at least one pair of non-equal elements.
Example:
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {1, 2, 4};
std::vector<int> v3 = {1, 2, 3};
assert_not_equal(v1, v2); // Passes (different at index 2)
assert_not_equal(v1, v3); // Throws fail_assertion (all elements equal)
Checks that each element in the first range is less than the corresponding element in the second range.
Example:
std::vector<int> smaller = {1, 3, 5};
std::vector<int> larger = {2, 4, 6};
std::vector<int> mixed = {2, 2, 6};
assert_lt(smaller, larger); // Passes (1<2, 3<4, 5<6)
assert_lt(smaller, mixed); // Throws fail_assertion (3 >= 2)
Applies a comparison function to each corresponding pair of elements from two ranges.
Example:
std::vector<int> v1 = {1, 4, 9};
std::vector<int> v2 = {1, 2, 3};
// Custom comparison: check if v1[i] == v2[i]²
assert_func(v1, v2, [](int a, int b) {
assert_equal(a, b * b);
}); // Passes (1==1², 4==2², 9==3²)
// Using existing assertion function
assert_func(v1, v2, [](int a, int b, auto loc) {
assert_lt(b, a, loc);
}); // Passes (1<1 fails, so this throws)
Checks that calling the given function throws one of the specified exception types. If no exception types are specified, checks that any exception is thrown.
Example:
// Check for any exception
assert_throw([]() {
throw std::runtime_error("error");
}); // Passes
// Check for specific exception type
assert_throw<std::runtime_error>([]() {
throw std::runtime_error("error");
}); // Passes
assert_throw([]() {
return 42;
}); // Throws fail_assertion (no exception thrown)
assert_expected_value
instead for new code.
Checks that an std::expected
contains a value (not an error).
Example:
std::expected<int, std::string> good_result = 42;
std::expected<int, std::string> bad_result = std::unexpected("error");
assert_expected(good_result); // Passes
assert_expected(bad_result); // Throws fail_assertion with error message
Checks that an std::expected
contains a value and returns that value. If it contains an error, throws a fail_assertion
.
Example:
std::expected<int, std::string> good_result = 42;
std::expected<int, std::string> bad_result = std::unexpected("error");
int value = assert_expected_value(std::move(good_result)); // Returns 42
int value2 = assert_expected_value(std::move(bad_result)); // Throws fail_assertion