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

Conversation

christophebedard
Copy link
Contributor

@christophebedard christophebedard commented Mar 16, 2020

As described in this answers.ros.org question, I was looking to generate coverage information for Python tests in a CMake package. The --pytest-with-coverage colcon option only applies to (pure) Python packages.

I borrowed some code from https://github.com/colcon/colcon-core/blob/af7fa089962a9e9a35926734e17b00cfb4c780a6/colcon_core/task/python/test/pytest.py#L77-L108.

I'm open to suggestions to

  • improve/replace/remove the need for AMENT_CMAKE_TEST_PYTEST_WITH_COVERAGE. I couldn't find a way to pass additional arguments/flags from the ctest invocation (done by colcon) through to the run_test.py script other than by using an environment variable.
  • improve or remove the need for AMENT_CMAKE_CURRENT_SOURCE_DIR
  • extract build_base in a more robust way

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
@christophebedard christophebedard force-pushed the cmake-packages-pytest-with-coverage-option branch from d7b7860 to 30769b3 Compare March 16, 2020 14:58
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
They were excluded before, but only because gtests didn't use --env or --append-end.

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
@dirk-thomas
Copy link
Contributor

Thanks for contributing this enhancement.

I was wondering about the decision where certain parts of the logic are located in the patch. I few thoughts so far:

  • The most natural choice for a CMake package to provide configuration options is to declare them with option(...). The default could be off or some heuristic as in colcon-core.
  • The CMake logic in ament_add_pytest_test.cmake is creating the command line to invoke pytest. It seems to more natural location to also add the necessary --cov arguments instead of doing that in ament_cmake_test/ament_cmake_test/__init__.py which than has to do awkward checks if the test is actually not a gtest. This would also avoid needing to pass AMENT_CMAKE_CURRENT_SOURCE_DIR. Also the package ament_cmake_test should have no knowledge about pytest - that should be fully encapsulated in the ament_cmake_pytest package.

@dirk-thomas dirk-thomas added enhancement New feature or request in progress Actively being worked on (Kanban column) labels Mar 26, 2020
@christophebedard
Copy link
Contributor Author

I was wondering about the decision where certain parts of the logic are located in the patch. I few thoughts so far:

Yeah, like I mentioned above, I wasn't really sure about some of the choices made for the PR, so I really appreciate this feedback!

  • The most natural choice for a CMake package to provide configuration options is to declare them with option(...). The default could be off or some heuristic as in colcon-core.

Sounds good. I wanted to make this a colcon test option, but then, as you can see, it requires weird workarounds.

In any way, enabling coverage for CMake packages already requires build time flags (for C and C++).

  • The CMake logic in ament_add_pytest_test.cmake is creating the command line to invoke pytest. It seems to more natural location to also add the necessary --cov arguments instead of doing that in ament_cmake_test/ament_cmake_test/__init__.py which than has to do awkward checks if the test is actually not a gtest. This would also avoid needing to pass AMENT_CMAKE_CURRENT_SOURCE_DIR. Also the package ament_cmake_test should have no knowledge about pytest - that should be fully encapsulated in the ament_cmake_pytest package.

Got it. Will address this soon.

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
@christophebedard
Copy link
Contributor Author

christophebedard commented Mar 28, 2020

Got it. Will address this soon.

@dirk-thomas see new commits (to be squashed eventually, or I can just open a new PR if you prefer)

Now with colcon/colcon-ros#101, ros.ament_cmake packages have a colcon build option (--ament-cmake-pytest-with-coverage) which defines AMENT_CMAKE_PYTEST_WITH_COVERAGE=1 to be checked by ament_cmake_pytest. I used an option(), but not every ros.ament_cmake package uses ament_cmake_pytest, therefore those that don't use it print warnings ("Manually-specified variables were not used by the project"). Not sure what the preferred solution is here, especially if I have to keep the option() in ament_cmake_pytest itself. Perhaps there's a hook somewhere?

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
@dirk-thomas dirk-thomas removed the in progress Actively being worked on (Kanban column) label Apr 2, 2020
@dirk-thomas
Copy link
Contributor

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@dirk-thomas
Copy link
Contributor

Thanks for the improvement.

@dirk-thomas dirk-thomas merged commit 1cc195d into ament:master Apr 3, 2020
@christophebedard christophebedard deleted the cmake-packages-pytest-with-coverage-option branch April 3, 2020 04:14
j-rivero pushed a commit that referenced this pull request Apr 27, 2020
)

* Enable coverage information generation for pytest tests with CMake

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Add comment about pytest-cov version requirement for --cov-branch

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Add --pytest-with-coverage to run_test.py and mention the env var

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Rename to AMENT_CMAKE_TEST_PYTEST_WITH_COVERAGE

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Fix missing quote

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Exclude gtests from pytest coverage explicitly

They were excluded before, but only because gtests didn't use --env or --append-end.

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Append pytest-cov flags in ament_add_pytest_test() directly

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Fix ament_has_pytest_cov()

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Change default logic to avoid overriding CLI params

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Remove --cov-append pytest_cov option

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Simplify indentation

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Remove QUIET arg from ament_has_pytest_cov()

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Change ament_has_pytest_cov() to ament_get_pytest_cov_version()

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Do not return() if pytest_cov is not found in ament_add_pytest_test()

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Fix missing empty <options> argument

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Simplify pytest_cov version regex match

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Write pytest_cov results to test-specific directory

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>

* Make sure to create test-specific pytest_cov directory

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Signed-off-by: Jose Luis Rivero <jrivero@osrfoundation.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants