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 TestContext {
int thread_count = 1;
TestSuite tests = TestSuite{};
TestTimeUnit time_unit = TestTimeUnit::MICRO_SECONDS;
}To obtain the global context, call jowi::test_lib::get_test_context(), this will return a reference to the test context.
TestContext& get_test_context();This sets the time unit used when logging the tests. Valid values are:
enum struct TestTimeUnit { 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 FailAssertion 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 FailAssertionChecks 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 FailAssertionChecks 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 FailAssertion
assert_lt(5, 5); // Throws FailAssertion (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 FailAssertion
assert_true(x > 0, "x must be positive"); // Custom error messageChecks that the given boolean expression evaluates to false.
Example:
assert_false(5 < 3); // Passes
assert_false(false); // Passes
assert_false(true); // Throws FailAssertion
assert_false(x < 0, "x should not be negative"); // Custom error messageChecks 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 FailAssertion
// 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 doubleChecks 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 FailAssertion at index 2Checks 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 FailAssertion (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 FailAssertion (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 FailAssertion (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 FailAssertion with error messageChecks that an std::expected contains a value and returns that value. If it contains an error, throws a FailAssertion.
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 FailAssertion