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

Include test suite in code coverage #870

Closed
wants to merge 2 commits into from

Conversation

cjolowicz
Copy link
Owner

@cjolowicz cjolowicz commented Apr 15, 2021

Closes #792

Include the test suite in code coverage, via the coverage.run.source setting.

Rationale:

  • Tests are code.
  • Identify tests that aren’t running.
  • Ensure that test helpers are used and tested.

Caveats:

  • Coverage may require extra configuration if tests are deliberately excluded.
  • Tests may clutter the coverage report; use --skip-covered for this.
  • The coverage metric generally goes up.

https://nedbatchelder.com/blog/202008/you_should_include_your_tests_in_coverage.html

This PR also enables the coverage.run.relative_files setting, to store paths relative to the repository in the coverage data files. By default, coverage data contains absolute paths for the test suite. During CI, coverage data from various runners is combined in an environment where these paths do not exist. This results in errors like the following:

No source for code: '/Users/runner/work/cookiecutter-hypermodern-python-instance/cookiecutter-hypermodern-python-instance/tests/__init__.py'.
Aborting report output, consider using -i.

The coverage.paths setting does not help with the test suite: Unlike the code under src, the test suite is not installed to site-packages, so we'd need to either hardcode paths from individual runners, or use overly generic wildcards. The setting is still needed for src though, because even the relative paths include the location of the various Nox environments.

@cjolowicz cjolowicz added the testing Adding missing tests or correcting existing tests label Apr 15, 2021
@cjolowicz cjolowicz added this to the 2021.4.15 milestone Apr 15, 2021
Rationale:

- Tests are code.
- Identify tests that aren’t running.
- Ensure that test helpers are used and tested.

Caveats:

- Coverage may require extra configuration if tests are deliberately excluded.
- Tests may clutter the coverage report; use `--skip-covered` for this.
- The coverage metric generally goes up.

https://nedbatchelder.com/blog/202008/you_should_include_your_tests_in_coverage.html
By default, coverage data contains absolute paths for the test suite. During CI,
coverage data from various runners is combined in an environment where these
paths do not exist. This results in errors like the following:

  No source for code:
  '/Users/runner/work/cookiecutter-hypermodern-python-instance/cookiecutter-hypermodern-python-instance/tests/__init__.py'.
  Aborting report output, consider using -i.

The `coverage.paths` setting does not help with the test suite: Unlike the code
under `src`, the test suite is not installed to `site-packages`, so we'd need to
either hardcode paths from individual runners, or use overly generic wildcards.

Instead, `coverage.run.relative_files` can be used to store the paths relative
to the repository. We still need `coverage.paths` for `src` though, because
these file paths still include the path into the various Nox environments.
@cjolowicz cjolowicz force-pushed the retrocookie-pr/coverage-for-tests branch from affed1b to eb31214 Compare April 15, 2021 13:53
@cjolowicz cjolowicz marked this pull request as draft April 15, 2021 14:04
@cjolowicz
Copy link
Owner Author

cjolowicz commented Apr 15, 2021

Converted to draft, because for generated projects this fails locally and in CI, see cjolowicz/cookiecutter-hypermodern-python-instance#545 . Looks like this needs some more time to figure out--a minimal repro and digging into Coverage.py's handling of relative_files and paths.

Job log:

Run nox --force-color --session=coverage
  nox --force-color --session=coverage
  shell: /usr/bin/bash -e {0}
  env:
    pythonLocation: /opt/hostedtoolcache/Python/3.9.4/x64
    LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.9.4/x64/lib
nox > Running session coverage
nox > Creating virtual environment (virtualenv) using python in .nox/coverage
nox > poetry export --format=requirements.txt --dev --without-hashes
nox > python -m pip install --constraint=/home/runner/work/cookiecutter-hypermodern-python-instance/cookiecutter-hypermodern-python-instance/.nox/coverage/tmp/requirements.txt coverage[toml]
nox > coverage combine
nox > coverage report
No source for code: '/home/runner/work/cookiecutter-hypermodern-python-instance/cookiecutter-hypermodern-python-instance/tests\__init__.py'.
Aborting report output, consider using -i.
nox > Command coverage report failed with exit code 1
nox > Session coverage failed.
Error: Process completed with exit code 1.

@cjolowicz cjolowicz modified the milestones: 2021.4.15, Backlog Apr 15, 2021
@cjolowicz
Copy link
Owner Author

This appears to have been fixed in Coverage 6.1.2, nedbat/coveragepy#1147.

@cjolowicz
Copy link
Owner Author

cjolowicz commented Nov 22, 2021

The coverage job still fails:

Run nox --force-color --session=coverage
  nox --force-color --session=coverage
  shell: /usr/bin/bash -e {0}
  env:
    pythonLocation: /opt/hostedtoolcache/Python/3.10.0/x64
    LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.10.0/x64/lib
nox > Running session coverage
nox > Creating virtual environment (virtualenv) using python in .nox/coverage
nox > poetry export --format=requirements.txt --dev --without-hashes
nox > python -m pip install --constraint=.nox/coverage/tmp/requirements.txt coverage[toml]
nox > coverage combine
Combined data file .coverage.Mac-1637583269253.local.2309.783152
Combined data file .coverage.fv-az219-596.1840.774631
Combined data file .coverage.fv-az201-683.1803.048679
Combined data file .coverage.fv-az177-592.2280.671354
Combined data file .coverage.fv-az290-259.1821.460664
Combined data file .coverage.fv-az154-786.1807.864427
nox > coverage report
No source for code: '/home/runner/work/cookiecutter-hypermodern-python-instance/cookiecutter-hypermodern-python-instance/tests\__init__.py'.
nox > Command coverage report failed with exit code 1
nox > Session coverage failed.
Error: Process completed with exit code 1.

EDIT: Locally the coverage session succeeds when running nox -s tests.

@cjolowicz cjolowicz self-assigned this Nov 22, 2021
@cjolowicz
Copy link
Owner Author

cjolowicz commented Nov 22, 2021

This is apparently triggered when coverage is reported on POSIX for coverage data generated on Windows, due to platform-dependent path separators. The following was run on macOS using the coverage-data artifact from GA:

❯ unzip coverage-data.zip
Archive:  coverage-data.zip
  inflating: .coverage.fv-az177-592.1636.348101
  inflating: .coverage.fv-az201-683.1804.431767
  inflating: .coverage.fv-az212-131.1805.250514
  inflating: .coverage.fv-az212-131.1812.943296
  inflating: .coverage.fv-az216-465.1796.196706
  inflating: .coverage.Mac-1637583275916.local.1913.585475

❯ nox -rs coverage
nox > Running session coverage
nox > Re-using existing virtual environment at .nox/coverage.
nox > python -m pip install --constraint=.nox/coverage/tmp/requirements.txt coverage[toml]
nox > coverage combine
Combined data file .coverage.fv-az201-683.1804.431767
Combined data file .coverage.fv-az177-592.1636.348101
Combined data file .coverage.fv-az212-131.1805.250514
Combined data file .coverage.Mac-1637583275916.local.1913.585475
Combined data file .coverage.fv-az216-465.1796.196706
Combined data file .coverage.fv-az212-131.1812.943296
nox > coverage report
No source for code: '/Users/cjolowicz/Code/github.com/cjolowicz/cookiecutter-hypermodern-python-instance/tests\__init__.py'.
nox > Command coverage report failed with exit code 1
nox > Session coverage failed.

❯ for file in .coverage.* ; do echo ; echo "==> $file";  sqlite3 $file 'select * from file' ; done

==> .coverage.Mac-1637583275916.local.1913.585475
1|tests/__init__.py
2|tests/test_main.py
3|.nox/tests-3-10/lib/python3.10/site-packages/cookiecutter_hypermodern_python_instance/__init__.py
4|.nox/tests-3-10/lib/python3.10/site-packages/cookiecutter_hypermodern_python_instance/__main__.py

==> .coverage.fv-az177-592.1636.348101
1|tests\__init__.py
2|tests\test_main.py
3|.nox\tests-3-10\Lib\site-packages\cookiecutter_hypermodern_python_instance\__init__.py
4|.nox\tests-3-10\Lib\site-packages\cookiecutter_hypermodern_python_instance\__main__.py

==> .coverage.fv-az201-683.1804.431767
1|tests/__init__.py
2|tests/test_main.py
3|.nox/tests-3-7/lib/python3.7/site-packages/cookiecutter_hypermodern_python_instance/__init__.py
4|.nox/tests-3-7/lib/python3.7/site-packages/cookiecutter_hypermodern_python_instance/__main__.py

==> .coverage.fv-az212-131.1805.250514
1|tests/__init__.py
2|tests/test_main.py
3|.nox/tests-3-9/lib/python3.9/site-packages/cookiecutter_hypermodern_python_instance/__init__.py
4|.nox/tests-3-9/lib/python3.9/site-packages/cookiecutter_hypermodern_python_instance/__main__.py

==> .coverage.fv-az212-131.1812.943296
1|tests/__init__.py
2|tests/test_main.py
3|.nox/tests-3-8/lib/python3.8/site-packages/cookiecutter_hypermodern_python_instance/__init__.py
4|.nox/tests-3-8/lib/python3.8/site-packages/cookiecutter_hypermodern_python_instance/__main__.py

==> .coverage.fv-az216-465.1796.196706
1|tests/__init__.py
2|tests/test_main.py
3|.nox/tests-3-10/lib/python3.10/site-packages/cookiecutter_hypermodern_python_instance/__init__.py
4|.nox/tests-3-10/lib/python3.10/site-packages/cookiecutter_hypermodern_python_instance/__main__.py

@cjolowicz
Copy link
Owner Author

The coverage session succeeds if the coverage data from Windows is removed prior to coverage combine.

❯ unzip coverage-data.zip
Archive:  coverage-data.zip
  inflating: .coverage.fv-az177-592.1636.348101
  inflating: .coverage.fv-az201-683.1804.431767
  inflating: .coverage.fv-az212-131.1805.250514
  inflating: .coverage.fv-az212-131.1812.943296
  inflating: .coverage.fv-az216-465.1796.196706
  inflating: .coverage.Mac-1637583275916.local.1913.585475

❯ rm .coverage.fv-az177-592.1636.348101

❯ nox -s coverage
nox > Running session coverage
nox > Creating virtual environment (virtualenv) using python in .nox/coverage
nox > poetry export --format=requirements.txt --dev --without-hashes
nox > python -m pip install --constraint=.nox/coverage/tmp/requirements.txt coverage[toml]
nox > coverage combine
Combined data file .coverage.fv-az201-683.1804.431767
Combined data file .coverage.fv-az212-131.1805.250514
Combined data file .coverage.Mac-1637583275916.local.1913.585475
Combined data file .coverage.fv-az216-465.1796.196706
Combined data file .coverage.fv-az212-131.1812.943296
nox > coverage report
Name                                                       Stmts   Miss Branch BrPart  Cover   Missing
------------------------------------------------------------------------------------------------------
src/cookiecutter_hypermodern_python_instance/__init__.py       0      0      0      0   100%
src/cookiecutter_hypermodern_python_instance/__main__.py       5      0      0      0   100%
tests/__init__.py                                              0      0      0      0   100%
tests/test_main.py                                             9      0      0      0   100%
------------------------------------------------------------------------------------------------------
TOTAL                                                         14      0      0      0   100%
nox > Session coverage was successful.

@cjolowicz
Copy link
Owner Author

Superceded by 5c5e256

@cjolowicz cjolowicz closed this Nov 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
testing Adding missing tests or correcting existing tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Include test suite in code coverage
1 participant