GithubHelp home page GithubHelp logo

pthom / cmake_registertest Goto Github PK

View Code? Open in Web Editor NEW
6.0 4.0 1.0 137 KB

cmake scripts for googletest / catch / doctest. Automatic tests registration, even inside library code.

C++ 13.70% CMake 86.30%
cmake-scripts cpp googletest catch doctest unit-testing cmake unit-tests static-library

cmake_registertest's Introduction

Cmake Register Test for libraries (crt)

This is a set of cmake utilites in order to make it easy to add unit tests to a C++ library, when using googletest, catch or doctest.

It provides a cmake function crt_registertest() with the following features :

  • Automatic discovery of the tests (outside of even inside the library source files)
  • Automatic creation of an executable target for the tests, and registration with ctest (i.e make test)
  • Automatic link the test target with the test library (providing an approriate main() function)
  • Automatic inclusion of the test library include path

Motto :

Tests code should be able to reside inside separate source files, as well as directly inside the library source files

The doctest documentation says rightfully:

Tests can be considered a form of documentation and should be able to reside near the production code which they test.

However, storing the test code is inside a library is often cumbersome : your tests might not be launched at all! The linker often strips the self-registration code when it is inside a library.

This project provides a solution that enables to have tests both inside the library sources, as well as inside separate source files.

For more information about the possible issues that this project attempts to solve, see:


Platforms

This project was tested under OSX, Windows and Linux

Requirements

Quick usage instructions

src/crt_registerstaticlibrary.cmake provides a crt_registertest() functions that make it possible to add tests to a library, using a simple instruction in the CMakeList.txt of your library.

Two cases are possible:

Case 1 : your test code resides in separate files

add_library(MyLibrary STATIC lib1.cpp)
crt_registertest(
  LIBRARY MyLibrary
  OUTPUT_TEST_TARGET MyLibraryTest
  TEST_SOURCES lib1_test.cpp
)

This will :

  1. Create an executable test target (MyLibraryTest) for your library.
  2. Register it as a cmake test (so that ctest or make test) will launch it.
  3. Link this test target with your library
  4. Append the test library include path to your TEST_SOURCES

For an example, see example_doctest_outertests:

Case 2 : your test code resides in the library source code (as well as separate files)

add_library(MyLibrary OBJECT lib1.cpp lib2.cpp)
crt_registertest(
  TEST_INPLACE  
  INPUT_OBJECT_LIBRARY MyLibrary
  OUTPUT_LIBRARY_NAME MyLibrary_Static
  OUTPUT_LIBRARY_TYPE STATIC
  OUTPUT_TEST_TARGET MyLibraryTest
  TEST_SOURCES lib3_test.cpp lib4_test.cpp 
)

This will :

  1. First compile your library source files (lib1.cpp and lib2.cpp) as an "object" library.
  2. Create a static or dynamic library from these files (see OUTPUT_LIBRARY_NAME and OUTPUT_LIBRARY_TYPE). Your source files will be compiled only once.
  3. Create an executable test target (MyLibraryTest) for your library.
  4. Register it as a cmake test (so that ctest or make test) will launch it.
  5. Append the test library include path to your TEST_SOURCES, as well as to the library sources
  6. Make sure that all tests are run (whether they are inside the library source files or inside TEST_SOURCES)

For an example, see example_doctest:

Detailed steps :

Step 1 : project structure

The structure of your project should resemble the tree shown below:

YourProject/
├── CMakeLists.txt
├── YourLibrary/
│   ├── CMakeLists.txt
│   ├── lib1.cpp
│   └── lib2.cpp
├── catch                         
│   ├── catch.hpp                 # Only one of 
├── doctest                       #  catch
│   ├── doctest.h                 #  doctest
├── gtest                         #  or googletest is required
│   ├── include/gtest/gtest.h     
|
└── cmake_registertest/           #  copy or reference cmake_registertest as a submodule at the root of your project
   └──   src
          ├── cpp_runners
          │   ├── catch_dynamic.cpp
          │   ├── catch_main.cpp
          │   ├── doctest_dynamic.cpp
          │   └── doctest_main.cpp
          ├── crt_registertest.cmake
          ├── crt_registertest_catch.cmake
          ├── crt_registertest_doctest.cmake
          └── crt_registertest_googletest.cmake

Step 2 : Modify your main CMakeList.txt file

Typical main CMakeList.txt file content (example using doctest)

cmake_minimum_required(VERSION 3.0)
project(my_project)
set (crt_test_lib_location ${CMAKE_SOURCE_DIR}/doctest)
include("${CMAKE_SOURCE_DIR}/cmake_registertest/src/crt_registertest_doctest.cmake")
enable_testing()
add_subdirectory(MyLibrary)
  1. Inside your main CMakeLists.txt, set the path to the include path of your test library (catch, doctest or googletest) Depending upon your test library, include one of the 3 lines below:
set (rsl_test_lib_location ${CMAKE_SOURCE_DIR}/catch)
set (rsl_test_lib_location ${CMAKE_SOURCE_DIR}/doctest)
set (rsl_test_lib_location ${CMAKE_SOURCE_DIR}/gtest/include)
  1. Include the script in your main CMakeLists.txt file After having set rsl_test_lib_location include the correct script.Depending upon your test library, include one of the 3 lines below:
include("${CMAKE_SOURCE_DIR}/cmake_registertest/src/crt_registertest_catch.cmake")
include("${CMAKE_SOURCE_DIR}/cmake_registertest/src/crt_registertest_googletest.cmake")
include("${CMAKE_SOURCE_DIR}/cmake_registertest/src/crt_registertest_doctest.cmake")
  1. enable tests for your project
enable_testing()

Step 3 : Register tests for your library

in the CMakeLists.txt of your library, call crt_registertest()

More info

See the examples

cmake_registertest's People

Contributors

pthom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

blockspacer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.