doctest / doctest

The fastest feature-rich C++11/14/17/20/23 single-header testing framework

Home Page:https://bit.ly/doctest-docs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Give example for having tests in production code

nlohmann opened this issue · comments

Description

I recently saw https://blog.jetbrains.com/rscpp/better-ways-testing-with-doctest/ where it was stated

What truly sets it apart is the ability to use it alongside your production code.

I would really like to try that. My expectation would be the following:

  • I have a large project containing of dozens of classes, each define in headers (.hpp) and implemented in source files (.cpp).
  • I would add test sections to each of the implementations (maybe at the bottom).
  • For "production" mode, I would compile the code as is - maybe defining or undefining some preprocessor symbol to switch off compilation of any test code.
  • For testing, I would like to reuse as much CMake code I already have and "just" recompile such that I have a single binary executing all the test distributed along the different implementation files.

Maybe my expectation is wrong, but in any case I would like to understand how the above quote is realizable in actual code.

Your assumptions are correct - it would be as easy as just including the header and writing test cases!

  • You'll need to use a doctest::Context object in your main() function to support the 3 logical scenarios: run only tests/run only the application/run both
  • to remove everything testing-related from the binaries you'll need to define DOCTEST_CONFIG_DISABLE globally
  • if your application is comprised of an executable + multiple shared objects then check this out - you'll need to compile the test runner in a separate shared object and link all other shared objects and the main executable to it

To get the fastest possible compile times of asserts checkout this part of the FAQ.

As for the CMake part - yes, you'll get a single binary with all the unit tests in it, but it will be up to you to call add_test() in CMake referencing the executable in order to register a ctest. You could use the --source-file=<filters> command line option on each call to add_test() with a different source file so tests from each .cpp end up in a different ctest. In fact that is what I've done in the doctest repository - I needed a single binary in order to generate a single coverage report but I wanted separate ctests for the separate .cpp files in the examples directory - here is the loop over the sources in CMake (using the short version of the --source-file command line option).

If your program has plugins (shared objects) which are loaded at runtime and they contain tests make sure to call the run() method of a doctest::Context only after loading them - makes sense, right? :)

You could even use doctest for asserts within the actual production code - even when being executed outside of a testing context!

You could write your tests at the bottom of the .cpp files for specific components, or you could add additional source files named something like <component>_tests.cpp so tests are easily distinguished from other sources - it's up to you. You could even write test cases in header files and they will still end up registered only once.

Let me know if you have any further questions!

I'll be closing this soon if there are no further questions

I created a gist with full example mixing production code with tests using static libraries (cmake object libraries actually). This way, you only compile the production code one time and have two main applications, the test runner and the default application which just works normally: https://gist.github.com/evandrocoan/2f53228503973b205a401c76dc9fcb13