Hello. I finally finished writing the fcfTest unit testing library (MIT License): https://github.com/fcf-framework/fcfTest https://github.com/fcf-framework/fcfTest Until now, the library consisted of just a single macro; however, it now fully implements all the necessary functionality. Its primary distinguishing feature lies in the use of a single assertion macro for all tests - a capability made possible by the fact that the library is written in C++. Furthermore, integrating it requires nothing more than a single header file. The library supports independent command-line processing, allows for specifying the test execution order, and most importantly - supports a hierarchical test structure organized into three levels: Section -> Group -> Test. It can also be compiled as a standalone DLL. Additionally, the library includes a simple logger (fcf::NTest::Duration::err() … fcf::NTest::log() … fcf::NTest::trc()) and a class for measuring execution duration (fcf::NTest::Duration). The main FCF_TEST macro - suitable for all scenarios: It allows for writing complex checks that include variable state monitoring. FCF_TEST(a==15, a); FCF_TEST(a==15, a); And in the terminal, you will see: Test error: a == 15 [FILE: DIR_PATH/main.cpp:LINE] Values: a: 1 Test error: a == 15 [FILE: DIR_PATH/main.cpp:LINE] Values: a: 1 The first parameter is a computed verification expression, while all other parameters are observed variables. ## Example Next follows the main example from this library; the accompanying comment explains the core mechanics of its operation. #include <vector> #include <cmath> // It is necessary to define the `FCF_TEST_IMPLEMENTATION` macro so that the // implementations are exposed when the header file is included. // If the `fcfTest/test.hpp` file is included multiple times within a project, // this macro should be defined in only one `.cpp` file. // // When working with DLLs, you must define both the `FCF_TEST_IMPLEMENTATION` // and `FCF_TEST_EXPORT` macros within the main library that exports // the functions; conversely, in libraries that import these functions, // you need to define only the `FCF_TEST_IMPORT` macro. #define FCF_TEST_IMPLEMENTATION #include <fcfTest/test.hpp> // --- Test Declarations --- FCF_TEST_DECLARE("Math" /*PART NAME*/, "BasicArithmetic" /*GROUP NAME*/, "Addition" /*TEST NAME*/) { // We create an object to measure execution duration // over 10,000 iterations. fcf::NTest::Duration bench(10000); // Set the starting time point for measuring execution time. bench.begin(); for(size_t i = 0; i < bench.iterations(); ++i) { int a = 2; int b = 3; // Performing a check of the unit test execution. FCF_TEST(a + b == 5, a, b); } // We set the final time point for measuring execution time. bench.end(); // Outputting the execution time measurement result at the 'info' logging level. fcf::NTest::inf() << " Itertion count: " << bench.iterations() << std::endl; fcf::NTest::inf() << " Total: " << bench.totalDuration().count() << " ns" << std::endl; fcf::NTest::inf() << " Avg: " << bench.duration().count() << " ns" << std::endl; } FCF_TEST_DECLARE("Math" /*PART NAME*/, "BasicArithmetic" /*GROUP NAME*/, "Subtraction" /*TEST NAME*/) { // We create an object to measure execution duration // over 10,000 iterations. fcf::NTest::Duration bench(10000); // We perform the task 10,000 times. bench([](){ int a = 10; int b = 4; // Performing a check of the unit test execution. FCF_TEST(a - b == 6, a, b); }); // Outputting the execution time measurement result at the 'info' logging level. fcf::NTest::inf() << " Itertion count: " << bench.iterations() << std::endl; fcf::NTest::inf() << " Total: " << bench.totalDuration().count() << " ns" << std::endl; fcf::NTest::inf() << " Avg: " << bench.duration().count() << " ns" << std::endl; } FCF_TEST_DECLARE("Vector" /*PART NAME*/, "SizeCheck" /*GROUP NAME*/, "EmptyVector" /*TEST NAME*/) { std::vector<int> v; FCF_TEST(v.size() == 0, v.size()); } // --- Order Registration --- // Run Math tests before Vector tests FCF_TEST_PART_ORDER("Math", 1); FCF_TEST_PART_ORDER("Vector", 2); // Run "BasicArithmetic" group first within Math part FCF_TEST_GROUP_ORDER("BasicArithmetic", 1); // Run Addition test first FCF_TEST_TEST_ORDER("Addition", 1); int main(int a_argc, char* a_argv[]) { // Use CRM_RUN for standard execution bool error; fcf::NTest::cmdRun(a_argc, (const char**)a_argv, fcf::NTest::CRM_RUN, &error); return error ? 1 : 0; } #include <vector> #include <cmath> // It is necessary to define the `FCF_TEST_IMPLEMENTATION` macro so that the // implementations are exposed when the header file is included. // If the `fcfTest/test.hpp` file is included multiple times within a project, // this macro should be defined in only one `.cpp` file. // // When working with DLLs, you must define both the `FCF_TEST_IMPLEMENTATION` // and `FCF_TEST_EXPORT` macros within the main library that exports // the functions; conversely, in libraries that import these functions, // you need to define only the `FCF_TEST_IMPORT` macro. #define FCF_TEST_IMPLEMENTATION #include <fcfTest/test.hpp> // --- Test Declarations --- FCF_TEST_DECLARE("Math" /*PART NAME*/, "BasicArithmetic" /*GROUP NAME*/, "Addition" /*TEST NAME*/) { // We create an object to measure execution duration // over 10,000 iterations. fcf::NTest::Duration bench(10000); // Set the starting time point for measuring execution time. bench.begin(); for(size_t i = 0; i < bench.iterations(); ++i) { int a = 2; int b = 3; // Performing a check of the unit test execution. FCF_TEST(a + b == 5, a, b); } // We set the final time point for measuring execution time. bench.end(); // Outputting the execution time measurement result at the 'info' logging level. fcf::NTest::inf() << " Itertion count: " << bench.iterations() << std::endl; fcf::NTest::inf() << " Total: " << bench.totalDuration().count() << " ns" << std::endl; fcf::NTest::inf() << " Avg: " << bench.duration().count() << " ns" << std::endl; } FCF_TEST_DECLARE("Math" /*PART NAME*/, "BasicArithmetic" /*GROUP NAME*/, "Subtraction" /*TEST NAME*/) { // We create an object to measure execution duration // over 10,000 iterations. fcf::NTest::Duration bench(10000); // We perform the task 10,000 times. bench([](){ int a = 10; int b = 4; // Performing a check of the unit test execution. FCF_TEST(a - b == 6, a, b); }); // Outputting the execution time measurement result at the 'info' logging level. fcf::NTest::inf() << " Itertion count: " << bench.iterations() << std::endl; fcf::NTest::inf() << " Total: " << bench.totalDuration().count() << " ns" << std::endl; fcf::NTest::inf() << " Avg: " << bench.duration().count() << " ns" << std::endl; } FCF_TEST_DECLARE("Vector" /*PART NAME*/, "SizeCheck" /*GROUP NAME*/, "EmptyVector" /*TEST NAME*/) { std::vector<int> v; FCF_TEST(v.size() == 0, v.size()); } // --- Order Registration --- // Run Math tests before Vector tests FCF_TEST_PART_ORDER("Math", 1); FCF_TEST_PART_ORDER("Vector", 2); // Run "BasicArithmetic" group first within Math part FCF_TEST_GROUP_ORDER("BasicArithmetic", 1); // Run Addition test first FCF_TEST_TEST_ORDER("Addition", 1); int main(int a_argc, char* a_argv[]) { // Use CRM_RUN for standard execution bool error; fcf::NTest::cmdRun(a_argc, (const char**)a_argv, fcf::NTest::CRM_RUN, &error); return error ? 1 : 0; } If you launch this application, you will see the following report: Performing the test: "Math" -> "BasicArithmetic" -> "Subtraction" ... Performing the test: "Math" -> "BasicArithmetic" -> "Addition" ... Performing the test: "Vector" -> "SizeCheck" -> "EmptyVector" ... All tests were completed. Number of tests: 3 Performing the test: "Math" -> "BasicArithmetic" -> "Subtraction" ... Performing the test: "Math" -> "BasicArithmetic" -> "Addition" ... Performing the test: "Vector" -> "SizeCheck" -> "EmptyVector" ... All tests were completed. Number of tests: 3 However, if you specify the logging level parameter beforehand: ./full-example --test-log-level inf ./full-example --test-log-level inf Then the result will be supplemented with information regarding execution speed. Performing the test: "Math" -> "BasicArithmetic" -> "Subtraction" ... Itertion count: 10000 Total: 65652 ns Avg: 6 ns Performing the test: "Math" -> "BasicArithmetic" -> "Addition" ... Itertion count: 10000 Total: 77750 ns Avg: 7 ns Performing the test: "Vector" -> "SizeCheck" -> "EmptyVector" ... All tests were completed. Number of tests: 3 Performing the test: "Math" -> "BasicArithmetic" -> "Subtraction" ... Itertion count: 10000 Total: 65652 ns Avg: 6 ns Performing the test: "Math" -> "BasicArithmetic" -> "Addition" ... Itertion count: 10000 Total: 77750 ns Avg: 7 ns Performing the test: "Vector" -> "SizeCheck" -> "EmptyVector" ... All tests were completed. Number of tests: 3 Help on the full set of commands can be obtained by passing the command-line parameter `--test-help` ./full-example --test-help ./full-example --test-help Test options: --test-run - Run tests --test-list - Displays a list of all tests --test-part PART_NAME - Run only tests from the part. The parameter can be used multiple times --test-group GROUP_NAME - Run only tests from the group. The parameter can be used multiple times --test-test TEST_NAME - Run only this test. The parameter can be used multiple times --test-log-level LEVEL - Logging level (VALUES: off, ftl, err, wrn, att, log, inf, dbg, trc) --test-help - Help message Test options: --test-run - Run tests --test-list - Displays a list of all tests --test-part PART_NAME - Run only tests from the part. The parameter can be used multiple times --test-group GROUP_NAME - Run only tests from the group. The parameter can be used multiple times --test-test TEST_NAME - Run only this test. The parameter can be used multiple times --test-log-level LEVEL - Logging level (VALUES: off, ftl, err, wrn, att, log, inf, dbg, trc) --test-help - Help message I hope this library is useful to you. It's part of a larger project with a long history of development, and a stable second version is currently being developed. The project is unknown and needs support, so if you're interested, subscribe to its resources. Links: Tumblr: https://www.tumblr.com/blog/fcfjs https://www.tumblr.com/blog/fcfjs Youtube: https://www.youtube.com/@fcfframework https://www.youtube.com/@fcfframework Github: https://github.com/fcf-framework/fcfTest https://github.com/fcf-framework/fcfTest Instagram: https://www.instagram.com/v.o.markin221/ https://www.instagram.com/v.o.markin221/