Skip to content

Commit

Permalink
Report code coverage via CodeCov.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-hen committed Oct 6, 2021
1 parent ce8c4ee commit 03728c4
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 91 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
/tests/MPh.ini
**/__pycache__
**/.pytest_cache
.coverage
coverage.xml
flake8.txt
.spyproject
.idea
Expand Down
3 changes: 2 additions & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Find the full [documentation on Read-the-Docs][docs].
https://img.shields.io/pypi/dm/MPh)](
https://pepy.tech/project/mph)
![coverage](
tests/coverage.svg?raw=true)
https://img.shields.io/codecov/c/github/MPh-py/MPh?token=02ZZ8ZJH3M)](
https://codecov.io/gh/MPh-py/MPh)
[![quality](
https://img.shields.io/lgtm/grade/python/github/MPh-py/MPh?label=quality)](
https://lgtm.com/projects/g/MPh-py/MPh)
Expand Down
1 change: 0 additions & 1 deletion deploy/build.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Builds the installation package."""
__license__ = 'MIT'

from subprocess import run
from pathlib import Path
Expand Down
33 changes: 24 additions & 9 deletions deploy/clean.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
"""Deletes cache and build artifacts."""
__license__ = 'MIT'
"""Deletes build and test artifacts."""

from pathlib import Path
from shutil import rmtree

root = Path(__file__).resolve().parent.parent

for folder in root.rglob('__pycache__'):
rmtree(folder, ignore_errors=True)
folders = [
root/'deploy'/'docs',
root/'deploy'/'coverage',
root/'deploy'/'dist',
root/'dist',
]
folder_names = [
'__pycache__',
'.pytest_cache',
]
for folder_name in folder_names:
for folder in root.rglob(folder_name):
folders.append(folder)
for folder in folders:
if folder.is_dir():
rmtree(folder, ignore_errors=True)

for folder in root.rglob('.pytest_cache'):
rmtree(folder)

for folder in ('docs', 'dist', 'coverage'):
rmtree(root/'deploy'/folder, ignore_errors=True)
files = [
root/'.coverage',
root/'coverage.xml',
]
for file in files:
if file.is_file():
file.unlink()
12 changes: 12 additions & 0 deletions deploy/codecov.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Uploads the coverage report to CodeCov."""

from subprocess import run
from pathlib import Path
from os import environ

token = environ.get('MPh_CodeCov_token', None)
if not token:
raise RuntimeError('CodeCov upload token not set in environment.')

root = Path(__file__).resolve().parent.parent.parent
run(['codecov', '--file', 'coverage.xml', '--token', token], cwd=root)
52 changes: 23 additions & 29 deletions deploy/coverage.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
"""Measures code coverage by test suite."""
__license__ = 'MIT'

"""
Measures code coverage by test suite.
We cannot just run pyTest on the entire test suite (in the `tests` folder
of the repo) because the individual scripts there all start a client in
their respective setup routine. That is, they all start the Java VM,
which will fail once pyTest gets to the second script in the sequence.
Instead, we run pyTest for each script seperately, with the coverage
plug-in enabled, and generate the coverage report incrementally.
If the coverage report file (`coverage.xml`) already exists, we instead
render it as HTML for inspection. This is helpful during development.
The coverage report may also be uploaded to an online service such as
CodeCov for each published release or even commit.
"""

from subprocess import run
from pathlib import Path
from sys import argv


here = Path(__file__).resolve().parent
root = here.parent
file = here/'coverage.sqlite'

rerun = 'rerun' in argv[1:]
append = 'append' in argv[1:]

if rerun and not append and file.exists():
file.unlink()

if file.exists() and not append:
print('Coverage report already exists.')
else:
command = ['pytest', '--cov', '--cov-append']
tests = ['config', 'discovery', 'server', 'client', 'client-server',
'stand-alone', 'node', 'model', 'processes']
file = root/'coverage.xml'
if not file.exists():
command = ['pytest', '--cov', '--cov-append', '--cov-report', 'xml']
tests = ['config', 'discovery', 'server', 'client', 'client-server',
'stand-alone', 'node', 'model', 'processes']
for test in tests:
run(command + [f'tests/test_{test}.py'], cwd=root)

print('Rendering coverage report.')
folder = (here/'coverage').relative_to(root)
run(['coverage', 'html', f'--directory={folder}'], cwd=root)

badge = root/'tests'/file.with_suffix('.svg').name
if badge.exists():
print('Coverage badge already exists.')
else:
print('Rendering coverage badge.')
run(['coverage-badge', '-f', '-o', str(badge)], cwd=root)
print('Rendering existing coverage report as HTML.')
folder = (here/'coverage').relative_to(root)
run(['coverage', 'html', f'--directory={folder}'], cwd=root)
1 change: 0 additions & 1 deletion deploy/publish.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Publishes the package on PyPI."""
__license__ = 'MIT'

from subprocess import run
from pathlib import Path
Expand Down
5 changes: 2 additions & 3 deletions deploy/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
* Bump version number and enter current date in `mph/__init__.py`.
* Add the release notes to `docs/releases.md`.
* Add a dedicated commit for the version bump.
* Tag the commit with the version number, for example: `git tag -a v1.0.4`.
* Enter the release notes as an annotation.
* Push the commit (but not the tag): `git push origin main`.
* Push to GitHub: `git push origin main`.
* Check that documentation built successfully on Read-the-Docs.
* Publish to PyPI by running `deploy/publish.py`.
* Check that meta information is correct on PyPI.
* Tag the commit with the version number, for example: `git tag v1.0.4`.
* Then push the tag: `git push --tags`.
* Activate, but hide, the build for the tag on Read-the-Docs.
* Force the `stable` branch to new release tag: `git branch -f stable`.
Expand Down
1 change: 0 additions & 1 deletion deploy/render.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Renders the documentation."""
__license__ = 'MIT'

from subprocess import run
from pathlib import Path
Expand Down
31 changes: 31 additions & 0 deletions deploy/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Runs all tests in the intended order.
This script does not use pyTest, but runs the test scripts as is,
in a subprocess. We impose the intended order, from the most basic
functionality to the high-level abstractions.
Pass 'log' as a command-line argument to have the scripts print log
messages to the console while the tests are running. Pass 'debug' to
increase the verbosity of the log.
"""

from subprocess import run
from pathlib import Path
from timeit import default_timer as now
import sys

tests = ['config', 'discovery', 'server', 'client', 'client-server',
'stand-alone', 'node', 'model', 'processes']
folder = Path(__file__).parent.parent / 'tests'
python = sys.executable
arguments = sys.argv[1:]
for test in tests:
print(f'test_{test}')
t0 = now()
process = run([python, f'test_{test}.py'] + arguments, cwd=folder)
if process.returncode == 0:
print(f'Passed in {now()-t0:.0f} s.')
else:
print(f'Failed after {now()-t0:.0f} s.')
print()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dynamic = ['version', 'description']

[project.optional-dependencies]
doc = ['Sphinx', 'Furo', 'MyST-parser', 'CommonMark']
test = ['pyTest', 'pyTest-cov', 'coverage-badge', 'flake8']
test = ['pyTest', 'pyTest-cov', 'flake8']

[project.urls]
Documentation = 'https://mph.readthedocs.io'
Expand Down
21 changes: 0 additions & 21 deletions tests/coverage.svg

This file was deleted.

22 changes: 0 additions & 22 deletions tests/run_all.py

This file was deleted.

3 changes: 1 addition & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ filterwarnings =
[coverage:run]
source = mph/
omit = mph/discovery.py
data_file = deploy/coverage.sqlite
relative_files = True

[coverage:report]
exclude_lines =
pragma: no cover
def check_environment
def location

0 comments on commit 03728c4

Please sign in to comment.