The lightest feature rich C++ single header testing framework

The doctest library is inspired by the unittest {} functionality of the D programming language and Python's docstrings - tests can be considered a form of documentation and should be able to reside near the production code which they test.

A complete example with a self-registering test that compiles to an executable looks like this:

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"

int factorial(int number) { return number <= 1 ? number : factorial(number - 1) * number; }

TEST_CASE("testing the factorial function") {
    CHECK(factorial(1) == 1);
    CHECK(factorial(2) == 2);
    CHECK(factorial(10) == 3628800);
}

Note how a standard C++ operator for the comparison is used - doctest has only one core assertion macro (instead of many for less than, equals, greater than...) - yet the full expression is decomposed and the left and right values are logged.

It is modeled after Catch which is currently the most popular and easy to use alternative for testing in C++


There are many C++ testing frameworks - Catch, Boost.Test, UnitTest++, lest, bandit, igloo, xUnit++, CppTest, CppUnit, CxxTest, cpputest, googletest, cute and many other.

What makes doctest different is that it is ultra light on compile times (by orders of magnitude) and is unintrusive.

The key differences between it and other testing libraries are:

  • Ultra light - below 10ms of compile time overhead for including the header in a source file
  • Offers a way to remove everything testing-related from the binary with the DOCTEST_CONFIG_DISABLE identifier
  • Doesn't pollute the global namespace (everything is in the doctest namespace) and doesn't drag any headers with it
  • Doesn't produce any warnings even on the most aggressive warning levels for MSVC/GCC/Clang
  • Very portable and well tested C++98 - per commit tested on CI with over 200 different builds (valgrind, sanitizers...)
  • Just one header and no external dependencies apart from the C/C++ standard library! (well... same as Catch...)

This allows the library to be used in more ways than any other - tests can be written directly in the production code!

  • This makes the barrier for writing tests much lower - you don't have to: 1. make a separate source file 2. include a bunch of stuff in it 3. add it to the build system and 4. add it to source control - You can just write the tests for a class or a piece of functionality at the bottom of it's source file - or even header file!
  • Tests in the production code can be thought of as documentation or up to date comments - showing how an API is used
  • Tests can be shipped to the customer with the software to diagnose a bug faster
  • TDD in C++ has never been easier!

The library can be used like any other if you don't like the idea of mixing production code and tests - check out the features

Language Standard License Version download Join the chat at https://gitter.im/onqtam/doctest Try it online

master branchLinux/OSX StatusWindows statusStatic Analysis
dev branchLinux/OSX StatusWindows status

Documentation


Contributing

Support the development of the project with donations! There is a list of planned features which are all important and big - see the roadmap. I work on this project in my spare time and every cent is a big deal. I took a break from working in the industry to make open source software.

Donate to support

Contributions in the form of issues and pull requests are welcome as well.

Open an issue for a discussion before making a pull request to make sure the contribution goes smoothly.

This framework has some design goals which must be kept. Make sure you have read the features and design goals page.

The master branch is the stable one with the latest release and the dev branch is on the bleeding edge.

All the framework tests (using ctest) have their output collected when the CMake TEST_MODE variable is set to COLLECT (making the new reference output) and later the tests are ran on the CI services (travis and appveyor) - their output is compared with the current reference output in the repository with the COMPARE mode (default mode is COMPARE).

Code should be formatted with a recent-enough clang-format using the config file in the root of the repo (or I will do it...)

Testing with compilers different from GCC/Clang/MSVC (and more platforms) is something the project would benefit from.