C++20 library that allows you to test your code at compile time. It's an extension of popular testing frameworks.
TEST_CASE("Example test case")
{
CONSTEXPR_SECTION("My compile-time test")
{
std::vector vec = {1, 3};
CONSTEXPR_REQUIRE(vec[0] == 1);
CONSTEXPR_REQUIRE(vec[0] + vec[1] == 5); // ❌ compilation error
};
}Works seamlessly with:
| ✅ Google Test | 👉 Example | 📃 Documentation |
| ✅ Catch2 | 👉 Example | 📃 Documentation |
| ✅ Doctest | 👉 Example | 📃 Documentation |
| ✅ Boost.Test | 👉 Example | 📃 Documentation |
ConsTest was initially a contribution of mine to Catch2, but the PR was not merged. So I decided to make it better using C++20 features (Catch2 requires C++17) and to make it compatible with other popular testing frameworks.
Lately, C++ has been criticized for its lack of memory safety.
Testing at compile time is the only way to guarantee your code doesn't lead to memory corruption issues. This is critical for writing safe libraries and software programs.
With ConsTest, you can:
- ✅ Test
constexprfunctions at compile time - ✅ Guarantee absence of undefined behavior and erroneous behavior in your tested code
- ✅ Ensure your code is free from memory leaks
// Catch2 example
TEST_CASE("Example test case")
{
CONSTEXPR_SECTION("Addition")
{
CONSTEXPR_REQUIRE(1 + 1 == 2);
CONSTEXPR_REQUIRE(2 + 2 == 5); // ❌ compilation error
};
}// GTest example
TEST(example_tests, non_transient_constexpr_evaluation)
{
CONSTEXPR_SECTION("std::sort and std::find")
{
std::vector vec = {5, 2, 8, 1, 9};
std::ranges::sort(vec);
CONSTEXPR_EXPECT_EQ(vec[0], 1);
CONSTEXPR_EXPECT_EQ(vec[4], 9);
auto it = std::ranges::find(vec, 8);
CONSTEXPR_ASSERT_TRUE(it != vec.end());
};
}// GTest example
TEST(example_tests, various_undefined_behavior) {
CONSTEXPR_SECTION("Out of bounds") {
std::vector vec = {1, 2, 3};
CONSTEXPR_EXPECT_EQ(vec[3], 3); // ❌ compilation error
};
CONSTEXPR_SECTION("Double delete")
{
auto* const a = new int{ 10 };
delete a;
delete a; // ❌ compilation error
};
CONSTEXPR_SECTION("Use after free")
{
auto* const a = new int{ 10 };
delete a;
auto b = *a + 1; // ❌ compilation error
};
}Warning
Note that some compilers may have bugs that allow code with undefined behavior to compile successfully in constant evaluated contexts, even though it violates the C++ standard.
// GTest example
TEST(example_tests, memory_leaks)
{
CONSTEXPR_SECTION("new, no delete")
{
auto* const a = new int{ 10 }; // ❌ compilation error
};
}Wrap your tests in CONSTEXPR_SECTION macros to ensure they are executed at compile time.
Prefix assertion macros from your testing framework with CONSTEXPR_ to enable compile-time assertions.
Refer to the documentation of your testing framework for more information:
- 👉 Google Test
- 👉 Catch2
- 👉 Doctest
- 👉 Boost.Test
So that it does not break your code coverage.
This is also important
because a call to a constexpr function might give different results at runtime.
- A compiler supporting C++20, especially
__cpp_lib_is_constant_evaluated
What you can test in ConsTest depends on your compiler and the C++ standard version you use.
CPMAddPackage("gh:teskann/constest@1.0.0")
target_link_libraries(your_target PRIVATE constest)
# Configure ConsTest for your testing framework
target_compile_definitions(your_target PRIVATE CONSTEST_CONFIG_XXX)Contributions are welcome. Whether it's bug reports, feature requests, or pull requests.