Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing as part of the build

I have a CMake project separated in three parts:

  1. Compilation of my libraries
  2. Compilation of many unit tests programs testing each precise subpart of those libraries
  3. Compilation of program samples using those libraries

My question is about the 2nd part. My unit tests executables are short binary programs with a main returning 0 on success, 1 on fail. I would like to integrate their running as part of the build.

Is it possible to use CMake to do one of those two solutions:

  • Run every unit test program and check return values and generate an error if any fail.
  • Generate a test script that would run and check every unit test program and check return values to yield an error if any fail.

I'm not looking for a complete CMake script code, a simple indication on what is possible with a link to corresponding documentation would be enough.

like image 676
Aracthor Avatar asked Oct 02 '15 06:10

Aracthor


2 Answers

See a similar problem and my answer here.

Mainly my recommendation is to add a POST_BUILD step to your unit test targets that runs ctest. If a POST_BUILD step does fail (return code is not 0), the build will fail.

Something like:

set(UNIT_TEST MyLibUnitTestTargetName)
add_test(NAME ${UNIT_TEST} COMMAND ${UNIT_TEST})
add_custom_command(
     TARGET ${UNIT_TEST}
     COMMENT "Run tests"
     POST_BUILD 
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
     COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -R "^${UNIT_TEST}$" --output-on-failures
)

This has the advantage that it runs like you would call ctest.

The short version - without add_test() / ctest - would be:

set(UNIT_TEST MyLibUnitTestTargetName)
add_custom_command(
     TARGET ${UNIT_TEST}
     COMMENT "Run tests"
     POST_BUILD 
     COMMAND ${UNIT_TEST}
)

References:

  • add_test()
  • add_custom_command()
  • How to run ctest after building my project with cmake
  • CMake: Running unit test as part of the build
like image 96
Florian Avatar answered Oct 07 '22 00:10

Florian


If you want your test binary to be preserved, even if tests fail, you can try something like this:

set(UNIT_TEST MyLibUnitTestTargetName)
add_test(NAME ${UNIT_TEST} COMMAND ${UNIT_TEST})
add_custom_target(run_unit_test ALL
    COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
    DEPENDS ${UNIT_TEST})

This will create a target that always runs your unit tests. However, because it's a separate target failure of that command will result in build failure, but not in removing the binary produced by your original UNIT_TEST target.

like image 45
Patrick Kostjens Avatar answered Oct 06 '22 23:10

Patrick Kostjens