Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable coverage information generation for pytest tests with CMake #226

Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7fd635d
Enable coverage information generation for pytest tests with CMake
christophebedard Mar 16, 2020
cd9a802
Add comment about pytest-cov version requirement for --cov-branch
christophebedard Mar 16, 2020
30769b3
Add --pytest-with-coverage to run_test.py and mention the env var
christophebedard Mar 16, 2020
411a1c6
Rename to AMENT_CMAKE_TEST_PYTEST_WITH_COVERAGE
christophebedard Mar 16, 2020
afa4eee
Fix missing quote
christophebedard Mar 16, 2020
657f106
Exclude gtests from pytest coverage explicitly
christophebedard Mar 16, 2020
6c2130c
Append pytest-cov flags in ament_add_pytest_test() directly
christophebedard Mar 28, 2020
bd082c2
Fix ament_has_pytest_cov()
christophebedard Mar 29, 2020
33c00d0
Change default logic to avoid overriding CLI params
christophebedard Apr 1, 2020
634e79b
Remove --cov-append pytest_cov option
christophebedard Apr 1, 2020
5756cf3
Simplify indentation
christophebedard Apr 1, 2020
64cca30
Remove QUIET arg from ament_has_pytest_cov()
christophebedard Apr 1, 2020
aad4240
Change ament_has_pytest_cov() to ament_get_pytest_cov_version()
christophebedard Apr 1, 2020
ab6cce4
Do not return() if pytest_cov is not found in ament_add_pytest_test()
christophebedard Apr 1, 2020
eb0b5c5
Fix missing empty <options> argument
christophebedard Apr 1, 2020
6a904f8
Simplify pytest_cov version regex match
christophebedard Apr 2, 2020
2334fbe
Write pytest_cov results to test-specific directory
christophebedard Apr 2, 2020
c414240
Make sure to create test-specific pytest_cov directory
christophebedard Apr 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ament_cmake_pytest/ament_cmake_pytest-extras.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ find_package(ament_cmake_test QUIET REQUIRED)

include("${ament_cmake_pytest_DIR}/ament_add_pytest_test.cmake")
include("${ament_cmake_pytest_DIR}/ament_has_pytest.cmake")
include("${ament_cmake_pytest_DIR}/ament_has_pytest_cov.cmake")
40 changes: 40 additions & 0 deletions ament_cmake_pytest/cmake/ament_add_pytest_test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,46 @@ function(ament_add_pytest_test testname path)
list(APPEND cmd "-We")
endif()

option(AMENT_CMAKE_PYTEST_WITH_COVERAGE
"Generate coverage information for Python tests"
OFF)

# enable pytest coverage automatically if the package test_depends on pytest_cov
if("python3-pytest-cov" IN_LIST ${PROJECT_NAME}_TEST_DEPENDS)
christophebedard marked this conversation as resolved.
Show resolved Hide resolved
set(AMENT_CMAKE_PYTEST_WITH_COVERAGE ON)
christophebedard marked this conversation as resolved.
Show resolved Hide resolved
endif()

if(AMENT_CMAKE_PYTEST_WITH_COVERAGE)
# check if pytest-cov is available
ament_has_pytest_cov(has_pytest_cov pytest_cov_version
QUIET PYTHON_EXECUTABLE "${ARG_PYTHON_EXECUTABLE}"
)
if(NOT has_pytest_cov)
message(WARNING
"The Python module 'pytest-cov' was not found, test coverage will not be produced "
"(e.g. on Ubuntu/Debian install the package 'python3-pytest-cov')")
return()
else()
dirk-thomas marked this conversation as resolved.
Show resolved Hide resolved
list(APPEND cmd
"--cov=${CMAKE_CURRENT_SOURCE_DIR}"
"--cov-report=html:${CMAKE_CURRENT_BINARY_DIR}/coverage.html"
"--cov-report=xml:${CMAKE_CURRENT_BINARY_DIR}/coverage.xml"
"--cov-append"
dirk-thomas marked this conversation as resolved.
Show resolved Hide resolved
)

if(pytest_cov_version VERSION_LESS "2.5.0")
message(WARNING
"Test coverage will be produced, but will not contain branch coverage information, "
"because the pytest extension 'cov' does not support it "
"(need 2.5.0, found '${pytest_cov_version}').")
else()
list(APPEND cmd "--cov-branch")
endif()

list(APPEND ARG_ENV "COVERAGE_FILE=${CMAKE_CURRENT_BINARY_DIR}/.coverage")
endif()
endif()

if(ARG_ENV)
set(ARG_ENV "ENV" ${ARG_ENV})
endif()
Expand Down
74 changes: 74 additions & 0 deletions ament_cmake_pytest/cmake/ament_has_pytest_cov.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2020 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#
# Check if the Python module `pytest-cov` was found and get its version if it is.
#
# :param var: the output variable name
# :type var: string
# :param version_var: the variable name for the version of pytest-cov found, only
# set if it was found
# :type version_var: string
# :param QUIET: suppress the CMake warning if pytest-cov is not found, if not set
# and pytest-cov was not found a CMake warning is printed
# :type QUIET: option
christophebedard marked this conversation as resolved.
Show resolved Hide resolved
# :param PYTHON_EXECUTABLE: absolute path to the Python interpreter to be used,
# default to the CMake variable with the same name returned by
# FindPythonInterp
# :type PYTHON_EXECUTABLE: string
#
# @public
#
function(ament_has_pytest_cov var version_var)
christophebedard marked this conversation as resolved.
Show resolved Hide resolved
cmake_parse_arguments(ARG "QUIET" "PYTHON_EXECUTABLE" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "ament_has_pytest_cov() called with unused arguments: "
"${ARG_UNPARSED_ARGUMENTS}")
endif()

if(NOT ARG_PYTHON_EXECUTABLE)
set(ARG_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
endif()

set(cmd "${ARG_PYTHON_EXECUTABLE}" "-m" "pytest" "--version")
execute_process(
COMMAND ${cmd}
RESULT_VARIABLE res
OUTPUT_VARIABLE output
ERROR_VARIABLE error)
if(res EQUAL 0)
# check if pytest-cov is in the list of plugins
# (actual output of the command is in ${error} and not ${output})
string(REGEX MATCH "pytest-cov-[0-9]\.[0-9]\.[0-9]" pytest_cov_full_version "${error}")
if(pytest_cov_full_version)
# extract version
string(REGEX MATCH "[0-9]\.[0-9]\.[0-9]" pytest_cov_version "${pytest_cov_full_version}")
set(${var} TRUE PARENT_SCOPE)
set(${version_var} ${pytest_cov_version} PARENT_SCOPE)
else()
if(NOT ARG_QUIET)
message(WARNING "Failed to find `pytest` plugin `pytest-cov`")
endif()
set(${var} FALSE PARENT_SCOPE)
endif()
else()
if(NOT ARG_QUIET)
string(REPLACE ";" " " cmd_str "${cmd}")
message(WARNING
"Failed to find Python module `pytest` which is needed "
"for `pytest-cov`: '${cmd_str}' returned error code ${res}")
endif()
set(${var} FALSE PARENT_SCOPE)
endif()
endfunction()