diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000..146151a521 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +source = avocado/, optional_plugins/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4981b7c11..5575e05c8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,9 +132,11 @@ jobs: - name: Run pre script run: ./cc-test-reporter before-build - name: Run script - run: make develop && ./selftests/run_coverage + run: | + python setup.py develop --user + ./selftests/run_coverage - name: Run post script - run: ./cc-test-reporter after-build + run: ./cc-test-reporter after-build --debug - run: echo "🥑 This job's status is ${{ job.status }}." diff --git a/avocado/plugins/runners/avocado_instrumented.py b/avocado/plugins/runners/avocado_instrumented.py index d4bec69575..a08ecceaa2 100644 --- a/avocado/plugins/runners/avocado_instrumented.py +++ b/avocado/plugins/runners/avocado_instrumented.py @@ -98,21 +98,21 @@ def _run_avocado(runnable, queue): messages.start_logging(runnable.config, queue) - if "COVERAGE_RUN" in os.environ: - from coverage import Coverage - - coverage = Coverage() - coverage.start() - instance = loader.load_test(test_factory) early_state = instance.get_state() early_state["type"] = "early_state" queue.put(early_state) - instance.run_avocado() + # running the actual test if "COVERAGE_RUN" in os.environ: - coverage.stop() + from coverage import Coverage + + coverage = Coverage(data_suffix=True) + with coverage.collect(): + instance.run_avocado() coverage.save() + else: + instance.run_avocado() state = instance.get_state() fail_reason = state.get("fail_reason") diff --git a/avocado/plugins/runners/python_unittest.py b/avocado/plugins/runners/python_unittest.py index c9a717efbe..de26d273d1 100644 --- a/avocado/plugins/runners/python_unittest.py +++ b/avocado/plugins/runners/python_unittest.py @@ -109,7 +109,16 @@ def _run_unittest(cls, module_path, module_class_method, queue): return runner = TextTestRunner(stream=stream, verbosity=0) - unittest_result = runner.run(suite) + # running the actual test + if "COVERAGE_RUN" in os.environ: + from coverage import Coverage + + coverage = Coverage(data_suffix=True) + with coverage.collect(): + unittest_result = runner.run(suite) + coverage.save() + else: + unittest_result = runner.run(suite) unittest_result_entries = None if len(unittest_result.errors) > 0: diff --git a/docs/source/guides/writer/chapters/integrating.rst b/docs/source/guides/writer/chapters/integrating.rst index 23150b7a3d..67c880982b 100644 --- a/docs/source/guides/writer/chapters/integrating.rst +++ b/docs/source/guides/writer/chapters/integrating.rst @@ -9,24 +9,16 @@ like which parts are being exercised by the tests, may help develop new tests. `Coverage.py`_ is a tool designed for measuring code coverage of Python programs. It runs monitoring the program's source, taking notes of which -parts of the code have been executed. - -It is possible to use Coverage.py while running Avocado Instrumented tests. -As Avocado spawn sub-processes to run the tests, the `concurrency` parameter -should be set to `multiprocessing`. +parts of the code have been executed. It is possible to use Coverage.py while +running Avocado Instrumented tests or Python unittests. To make the Coverage.py parameters visible to other processes spawned by -Avocado, create the ``.coveragerc`` file in the project's root folder. +Avocado, create the ``.coveragerc`` file in the project's root folder and set +``source`` parameter to your system under test. Following is an example:: [run] - concurrency = multiprocessing source = foo/bar - parallel = true - -According to the documentation of Coverage.py, when measuring coverage in -a multi-process program, setting the `parallel` parameter will keep the data -separate during the measurement. With the ``.coveragerc`` file set, one possible workflow to use Coverage.py to measure Avocado tests is:: @@ -43,6 +35,6 @@ coverage measurement. For other options related to `Coverage.py`_, visit the software documentation. .. note:: Currently coverage support is limited working only with - `ProcessSpawner` (the default spawner). + `ProcessSpawner` (the default spawner) and Coverage.py>=7.5. .. _Coverage.py: https://coverage.readthedocs.io/ diff --git a/requirements-dev.txt b/requirements-dev.txt index 3faaada25d..ed1b5ee31f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,7 +7,7 @@ pylint==2.17.2 autopep8==1.6.0 black==24.3.0 -coverage==5.5 +coverage==7.5 # To run make check psutil==5.9.5 diff --git a/selftests/run b/selftests/run deleted file mode 100755 index 44e7905783..0000000000 --- a/selftests/run +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -__author__ = 'Lucas Meneghel Rodrigues ' - -import sys -import unittest - -from selftests.utils import test_suite - -if __name__ == '__main__': - runner = unittest.TextTestRunner(verbosity=1, - resultclass=unittest.TextTestResult) - result = runner.run(test_suite()) - if result.failures or result.errors: - sys.exit(1) diff --git a/selftests/run_coverage b/selftests/run_coverage index 9457131035..22583020b7 100755 --- a/selftests/run_coverage +++ b/selftests/run_coverage @@ -15,8 +15,8 @@ echo "Using coverage utility: $COVERAGE" $COVERAGE erase rm -f .coverage.* -RUNNING_COVERAGE=1 AVOCADO_CHECK_LEVEL=1 UNITTEST_AVOCADO_CMD="$COVERAGE run -p --include 'avocado/*,optional_plugins/*' $PYTHON -m avocado" $COVERAGE run -p --include "avocado/*,optional_plugins/*" ./selftests/run -$COVERAGE combine .coverage* +$COVERAGE run selftests/check.py --skip=static-checks +$COVERAGE combine echo $COVERAGE report -m --include "avocado/core/*" echo