Simple, easy-to-use, efficient testing library, for C, C++. It's not particularly great, but it's small and portable enough to be bundled with other, more important, libraries.
xTests is a testing library for C and C++. Specifically, it is a small, lightweight, portable, simple unit- and component-test framework suitable for exercising C and C++ libraries. Its primary design features are:
- Portability. It relies on no platform-specific or compiler-specific constructs. The only library it relies on is the 100% header-only, open-source STLSoft library. It works with a large number of C/C++ compilers. Importantly, it is sufficiently simple and lightweight that it is bundled with several other open-source libraries, and is an integral part of their automated unit- and component-testing in their builds;
- Simplicity. It doesn't require pre-processing of your source code by scripting languages. It doesn't use macros to create secret classes that use Schwarz counters to register test cases. It relies on you to simply code what you want, and nothing that you don't want.
xTests is completely free and includes source released under a BSD-style license.
Detailed instructions — via CMake, via bundling — are provided in the accompanying INSTALL.md file.
xTests is organised around a test runner, test cases, and typed assertion macros. Include xtests/xtests.h for the canonical XTESTS_* API, or xtests/terse-api.h for short aliases such as TEST_INT_EQ.
The full catalog — every public runner, case, assertion, and utility construct, with a short example for each — is in COMPONENTS.md.
A typical program parses verbosity, starts a runner, executes cases, prints results, and ends the runner. The Examples below show complete programs.
Extensive examples are provided in the examples directory, along with a markdown description for each. Below are the simplest-possible starting examples for both C and C++, followed by a more complete C scenario.
#include <xtests/xtests.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int retCode = EXIT_SUCCESS;
int verbosity;
XTESTS_COMMANDLINE_PARSE_VERBOSITY(argc, argv, &verbosity);
if (XTESTS_START_RUNNER("minimal_c_test", verbosity))
{
if (XTESTS_CASE_BEGIN("math", "Checking basic addition"))
{
XTESTS_TEST_INTEGER_EQUAL(4, 2 + 2);
XTESTS_CASE_END("math");
}
XTESTS_PRINT_RESULTS();
XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode);
}
return retCode;
}#include <xtests/xtests.h>
#include <vector>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int retCode = EXIT_SUCCESS;
int verbosity;
XTESTS_COMMANDLINE_PARSE_VERBOSITY(argc, argv, &verbosity);
if (XTESTS_START_RUNNER("minimal_cpp_test", verbosity))
{
if (XTESTS_CASE_BEGIN("vector", "Checking vector size"))
{
std::vector<int> v;
v.push_back(42);
XTESTS_TEST_INTEGER_EQUAL(1, v.size());
XTESTS_CASE_END("vector");
}
XTESTS_PRINT_RESULTS();
XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode);
}
return retCode;
}Here is a more complete C example illustrating the use of the terse assertion API and separate test case functions:
/* file: example.c.factorial.c */
#include <xtests/terse-api.h>
#include <stdio.h>
#include <assert.h>
/* a somewhat-flaky factorial function */
int factorial(int v)
{
assert(v >= 0);
switch (v)
{
case 0:
case 1:
return 1;
default:
return v * factorial(v - 1);
}
}
void test_factorial_edge_cases()
{
TEST_INT_EQ(1, factorial(0));
TEST_INT_EQ(1, factorial(1));
}
int main(int argc, char* argv[])
{
int retCode = EXIT_SUCCESS;
int verbosity;
XTESTS_COMMANDLINE_PARSE_VERBOSITY(argc, argv, &verbosity);
if (XTESTS_START_RUNNER("example.factorial.runner", verbosity))
{
/* runs test case function "test_factorial_edge_cases" */
XTESTS_RUN_CASE_WITH_DESC(test_factorial_edge_cases, "checking edge cases");
/* runs test case "test-case-range" */
if (XTESTS_CASE_BEGIN("test-case-range", "checking wider range of input numbers"))
{
TEST_INT_EQ(2, factorial(2));
TEST_INT_EQ(6, factorial(3));
/* . . . */
TEST_INT_EQ(479001600, factorial(12));
XTESTS_CASE_END("test-case-1");
}
XTESTS_PRINT_RESULTS();
XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode);
}
return retCode;
}NOTE: C++ test programs have additional support for facilities such as the throwing of exceptions and native C++ User-Defined Type (UDT) comparisons.
Compiler/language pairs exercised for xTests (library, examples, and tests) with the public STLSoft dependency. Legend: ✅ ok, ❌ fail.
All cells below passed configure+build in the language×toolchain CI survey (Clang Linux/macOS, GCC Linux, MinGW, Visual C++ 17.x). Default CI remains the modular cell / install-smoke / stlsoft-routes layout; override standards via prepare_cmake.sh
--c-standard/--cxx-standardwhen re-checking a pair.
| C++ | C | Clang (Linux) | Clang (macOS) | GCC (Linux) | GCC(MinGW) (Windows) | Visual C++ 17.x (Windows) |
|---|---|---|---|---|---|---|
| 23 | 23 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 23 | 17 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 20 | 23 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 20 | 17 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 20 | 11 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 20 | 99 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 20 | 90 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 17 | 17 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 17 | 11 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 17 | 99 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 17 | 90 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 14 | 11 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 14 | 99 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 14 | 90 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 11 | 11 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 11 | 99 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 11 | 90 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 98 | 99 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 98 | 90 | ✅ | ✅ | ✅ | ✅ | ✅ |
Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/xTests.
If you'd like to help out with the project, please raise an issue via GitHub Page - you'll be very welcome!
xTests has two dependencies:
- STLSoft 1.11 is required, both for the implementation and for the interface, providing:
- essential compiler and platform discrimination;
- string compatibility;
- string conversions (for C++ API);
- meta-programming (for C++ API);
- shwild is an optional dependency, which, if present, supports the string matching tests:
XTESTS_TEST_MULTIBYTE_STRING_MATCHES(pattern, value);XTESTS_TEST_MULTIBYTE_STRING_DOES_NOT_MATCH(pattern, value);
Projects in which xTests is used for testing include:
- b64;
- chomp;
- CLASP;
- collect-c;
- collect-cxx;
- cstring;
- Diagnosticism;
- FastFormat;
- libCLImate;
- libpath;
- lstrip;
- mksock;
- Pantheios.Extras.AtExit;
- Pantheios.Extras.DiagUtil;
- Pantheios.Extras.Main;
- Pantheios.Extras.xHelpers;
- Pantheios;
- recls;
- rstrip;
- ss-win-diskutil;
- STLSoft;
- STLSoft-1.10 (now deprecated);
- STLSoft-1.11 (now deprecated);
- SyLVReDxx;
- UNIXem;
- xTests;
xTests is released under the 3-clause BSD license. See LICENSE for details.