Skip to content

Instantly share code, notes, and snippets.

@evandrocoan
Last active March 11, 2024 15:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save evandrocoan/2f53228503973b205a401c76dc9fcb13 to your computer and use it in GitHub Desktop.
Save evandrocoan/2f53228503973b205a401c76dc9fcb13 to your computer and use it in GitHub Desktop.
Simple C++ program example to run tests together with your code using doctest.

C++ code example for tests and code together

Using conan package for doctest: https://conan.io/center/doctest?tab=useit

Create the *.cpp files inside a source directory as specified by CMakeLists.txt.

# for Linux/macOS
cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug  # -DENABLE_TESTING=OFF
cmake --build build/debug

# for Windows and Visual Studio 2017
cmake -S . -B build/debug -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=Debug  # -DENABLE_TESTING=OFF
cmake --build build/debug --config Debug

Running things:

./build/debug/main
./build/debug/main_tests
./build/debug/main_tests -tc="01*"
./build/debug/main_tests -tc="01*" -sc="01*"
./build/debug/main_tests -tc="01*" -sc="01*" -s
(cd ./build/debug && ctest --verbose)
make test -C ./build/debug ARGS='--verbose'
cmake --build ./build/debug --target test -- ARGS="--verbose"

Explicitly calling conan for build (CMakeLists.txt call already calls it if it was not called once):

# for Linux/macOS
conan install . --install-folder build/debug --build=missing -pr:b default -s build_type=Debug
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=build/debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug  # -DENABLE_TESTING=OFF
cmake --build build

# for Windows and Visual Studio 2017
conan install . --output-folder build/debug --build=missing -pr:b default -s build_type=Debug
cmake -S . -B build/debug -G "Visual Studio 15 2017" -DCMAKE_TOOLCHAIN_FILE=build/debug/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug  # -DENABLE_TESTING=OFF
cmake --build build/debug --config Debug
user@pc:(main)~/test$ cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug # -DENABLE_TESTING=OFF
Conan not setup, running conan build...
Configuration (profile_host):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Debug
compiler=gcc
compiler.libcxx=libstdc++
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]
Configuration (profile_build):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]
conanfile.txt: Installing package
Requirements
doctest/2.4.8 from 'conancenter' - Cache
Packages
doctest/2.4.8:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache
Installing (downloading, building) binaries...
doctest/2.4.8: Already installed!
conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
conanfile.txt: Generator txt created conanbuildinfo.txt
conanfile.txt: Aggregating env generators
conanfile.txt: Generated conaninfo.txt
conanfile.txt: Generated graphinfo
Using Conan toolchain through /root/test/build/debug/conan_toolchain.cmake.
-- The CXX compiler identification is GNU 9.3.0
-- Check for working CXX compiler: /usr/bin/c++
Using Conan toolchain through .
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
Using Conan toolchain through .
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Target declared 'doctest::doctest'
-- Conan: Including build module from '/root/.conan/data/doctest/2.4.8/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/lib/cmake/doctest.cmake'
=====> ENABLE_TESTING: ON.
-- Configuring done
-- Generating done
-- Build files have been written to: /root/test/build/debug
user@pc:(main)~/test$ cmake --build build/debug
Scanning dependencies of target mainstatic
[ 20%] Building CXX object CMakeFiles/mainstatic.dir/source/code_with_tests.cpp.o
[ 20%] Built target mainstatic
Scanning dependencies of target main_tests
[ 40%] Building CXX object CMakeFiles/main_tests.dir/source/main_tests.cpp.o
[ 60%] Linking CXX executable main_tests
[ 60%] Built target main_tests
Scanning dependencies of target main
[ 80%] Building CXX object CMakeFiles/main.dir/source/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main
user@pc:(main)~/test$ ./build/debug/main
The root of 9 is 81.
user@pc:(main)~/test$ ./build/debug/main_tests
[doctest] doctest version is "2.4.8"
[doctest] run with "--help" for options
===============================================================================
[doctest] test cases: 1 | 1 passed | 0 failed | 0 skipped
[doctest] assertions: 2 | 2 passed | 0 failed |
[doctest] Status: SUCCESS!
user@pc:(main)~/test$
cmake_minimum_required( VERSION 3.15 )
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan_toolchain.cmake")
message("Conan not setup, running conan build...")
execute_process(
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE EXECUTE_PROCESS_RETURN_VALUE
COMMAND conan install conanfile.txt -if "${CMAKE_BINARY_DIR}" --build missing -pr:b default -s build_type=${CMAKE_BUILD_TYPE}
)
endif()
set( CMAKE_TOOLCHAIN_FILE "${CMAKE_BINARY_DIR}/conan_toolchain.cmake" )
project( doctest_project CXX )
find_package( doctest )
option( ENABLE_TESTING "Build unit tests" ON )
message( "=====> ENABLE_TESTING: ${ENABLE_TESTING}." )
# Tests inside a static library - https://github.com/doctest/doctest/issues/21
# Split common .cpp files into a static lib to not compile them twice,
# one for the main and another for the main_tests target.
ADD_LIBRARY( mainstatic OBJECT
"source/code_with_tests.cpp"
)
target_link_libraries( mainstatic PUBLIC
doctest::doctest
)
target_include_directories( mainstatic PUBLIC
"source"
)
add_executable( main
"source/main.cpp"
)
target_include_directories( main PUBLIC
"source"
)
target_link_libraries( main PUBLIC
mainstatic
doctest::doctest
)
if(ENABLE_TESTING)
enable_testing()
add_executable( main_tests
"source/main_tests.cpp"
)
add_test( NAME main_tests COMMAND main_tests)
target_include_directories( main_tests PUBLIC
"source"
)
target_link_libraries( main_tests PUBLIC
mainstatic
doctest::doctest
)
else()
add_definitions( "-DDOCTEST_CONFIG_DISABLE" )
endif()
#include "code_with_tests.hpp"
int root(int number) {
return number * number;
}
TEST_CASE("01. Square function")
{
int inputValue;
int readExpected;
SUBCASE("01.") {
inputValue = 10;
readExpected = 100;
}
SUBCASE("02.") {
inputValue = 9;
readExpected = 81;
}
CHECK( root(inputValue) == readExpected );
}
#include <doctest/doctest.h>
int root(int number);
[requires]
doctest/2.4.8
[generators]
CMakeDeps
CMakeToolchain
#define DOCTEST_CONFIG_IMPLEMENT
#include <doctest/doctest.h>
#include <cstdio>
#include "code_with_tests.hpp"
int main(int argc, char const *argv[]) {
int input = 9;
fprintf(stderr, "The root of %d is %d.\n", input, root(input));
return 0;
}
// Do not compile the main class object with the tests to speed up compilation!
// https://github.com/doctest/doctest/issues/53#issuecomment-315173323
// #define DOCTEST_CONFIG_NO_POSIX_SIGNALS // catch segfault on gdb
#define DOCTEST_CONFIG_IMPLEMENT
#include <doctest/doctest.h>
// Call ./main_test -tc="01*" -sc="01*" in a terminal to only run the firts test and first subcase
// https://github.com/doctest/doctest/blob/master/doc/markdown/main.md
int main(int argc, char** argv)
{
doctest::Context context;
context.applyCommandLine(argc, argv);
int res = context.run();
// some teardown?
if(context.shouldExit()) {
return res;
}
// the application code if the tests were not run
return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment