Last active
April 21, 2019 10:08
-
-
Save dnmiller/6348584 to your computer and use it in GitHub Desktop.
CMake custom target for adding Python tests and GoogleTest unit tests to compiled libraries. Tests are run via nose.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Custom cmake target for creating a target using gtest for unit testing. | |
function(add_gtest_target TARGET_NAME TARGET_LIB) | |
set(TEST_EXEC _${TARGET_LIB}_test) | |
# Build the test executable. | |
add_executable(${TEST_EXEC} ${ARGN}) | |
target_link_libraries(${TEST_EXEC} ${TARGET_LIB}) | |
# gtest was not found with a find_package command and must be linked to | |
# explicitly. | |
target_link_libraries(${TEST_EXEC} gtest_main) | |
# This adds the "make test" target. | |
add_custom_target(${TARGET_NAME} | |
COMMAND ${TEST_EXEC} | |
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | |
COMMENT "Running tests.") | |
endfunction() | |
function(add_gtest_coverage_target TARGET_NAME OUTPUT_NAME TEST_SOURCES) | |
# Check prereqs | |
find_program(LCOV_PATH lcov) | |
find_program(GENHTML_PATH genhtml) | |
if (NOT LCOV_PATH) | |
message(FATAL_ERROR "lcov not found! Aborting...") | |
endif() | |
if (NOT GENHTML_PATH) | |
message(FATAL_ERROR "genhtml not found! Aborting...") | |
endif() | |
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") | |
message(WARNING "Code coverage results with a non-Debug build may be misleading" ) | |
endif() | |
set(EXEC_NAME _${TARGET_NAME}_coverage) | |
add_executable(${EXEC_NAME} ${TEST_SOURCES}) | |
# Link to the coverage libraries. | |
target_link_libraries(${EXEC_NAME} profile_rt) | |
# Link to google test libraries. | |
target_link_libraries(${EXEC_NAME} gtest_main) | |
# Add flags for debugging and for code coverage tests. | |
set_target_properties(${EXEC_NAME} PROPERTIES COMPILE_FLAGS | |
"-g -Wall -Wextra -fprofile-arcs -ftest-coverage") | |
set_target_properties(${EXEC_NAME} PROPERTIES LINKER_FLAGS | |
"-fprofile-arcs -ftest-coverage -lgcov") | |
# Create... | |
add_custom_target(${TARGET_NAME} | |
COMMAND ${LCOV_PATH} --directory . --zerocounters | |
COMMAND ${EXEC_NAME} | |
# Capture lcov counters | |
COMMAND ${LCOV_PATH} | |
--directory . --capture --output-file ${OUTPUT_NAME}.info | |
# Remove googletest coverage results | |
COMMAND ${LCOV_PATH} | |
--remove ${OUTPUT_NAME}.info '/usr/*' 'gtest*' 'include/*' | |
--output-file ${OUTPUT_NAME}.info.cleaned | |
COMMAND ${GENHTML_PATH} | |
-o ${OUTPUT_NAME} ${OUTPUT_NAME}.info.cleaned --legend -s | |
COMMAND ${CMAKE_COMMAND} | |
-E remove ${OUTPUT_NAME}.info ${OUTPUT_NAME}.info.cleaned | |
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | |
COMMENT "Generating code coverage results.") | |
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD | |
COMMENT "Open ./test/${OUTPUT_NAME}/index.html in your browser to | |
view the coverage report.") | |
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Custom cmake target for running nosetests on compiled libraries. | |
# | |
# This creates a custom target for running nosetests with the intent of | |
# verifying a compiled library using interpreted Python unit tests. It is | |
# meant to be used in addition to, not in lieu of, compiled unit test code. | |
# This can be particularly useful for math-heavy code where a compiled unit | |
# test could be quite cumbersome. The Python test code is responsible for | |
# importing the libraries (probably using ctypes). | |
# | |
# Usage: | |
# | |
# add_python_test_target(TARGET_NAME LIBRARY_DEPENDENCY SOURCE_FILES) | |
# | |
# Released into the public domain. No warranty implied. | |
find_program(NOSETESTS_PATH nosetests) | |
if(NOT NOSETESTS_PATH) | |
message(WARNING | |
"nosetests not found! Python library tests will not be available.") | |
endif() | |
function(add_python_test_target TARGET_NAME TARGET_LIB) | |
# Try again to find nosetests here. We may have switched virtualenvs or | |
# something since first running cmake. | |
find_program(NOSETESTS_PATH nosetests) | |
if(NOT NOSETESTS_PATH) | |
message(FATAL_ERROR "nosetests not found! Aborting...") | |
endif() | |
set(COPY_DIR ${CMAKE_BINARY_DIR}/${TARGET_NAME}_files) | |
add_custom_target(${TARGET_NAME} | |
COMMAND ${NOSETESTS_PATH} | |
WORKING_DIRECTORY ${COPY_DIR} | |
COMMENT "Running Python tests.") | |
# Copy Python files to the local binary directory so they can find the | |
# dynamic library. | |
set(COPY_TARGET ${TARGET_NAME}_copy) | |
# We add a separate target for copying Python files. This way we can set | |
# it as a dependency for the nosetests target. | |
add_custom_target(${COPY_TARGET}) | |
# Make sure the directory exists before we copy the files. | |
add_custom_command(TARGET ${COPY_TARGET} | |
COMMAND ${CMAKE_COMMAND} -E make_directory ${COPY_DIR}) | |
# Add commands to copy each file in the list of sources. | |
foreach(pysource ${ARGN}) | |
add_custom_command(TARGET ${COPY_TARGET} | |
COMMAND ${CMAKE_COMMAND} -E copy | |
${CMAKE_CURRENT_SOURCE_DIR}/${pysource} ${COPY_DIR}) | |
endforeach() | |
get_target_property(TARGET_LIB_NAME ${TARGET_LIB} LOCATION) | |
# Add a command to copy the target library into the same folder as the | |
# python files. | |
add_custom_command(TARGET ${COPY_TARGET} | |
COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_LIB_NAME} ${COPY_DIR} | |
) | |
# Make the copy target a dependency of the testing target to ensure it | |
# gets done first. | |
add_dependencies(${TARGET_NAME} ${COPY_TARGET}) | |
add_dependencies(${COPY_TARGET} ${TARGET_LIB}) | |
endfunction() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
PythonLibTest.cmake: Line 57 produces a warning since cmake-3.5.1
One can use
$<TARGET_FILE:${TARGET_LIB}>
instead of Line 57 and${TARGET_LIB_NAME}
in Line 62.