Skip to content

Commit 4004721

Browse files
committed
Fix coverage.
1 parent d5f2343 commit 4004721

File tree

9 files changed

+69
-35
lines changed

9 files changed

+69
-35
lines changed

.meta.toml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://github.com/zopefoundation/meta/tree/master/src/zope/meta/pure-python
33
[meta]
44
template = "pure-python"
5-
commit-id = "462fe60b"
5+
commit-id = "f11c758e"
66

77
[python]
88
with-sphinx-doctests = false
@@ -21,13 +21,22 @@ testenv-deps = [
2121
"pytest-cov",
2222
"pytest-remove-stale-bytecode",
2323
]
24+
coverage-setenv = [
25+
"COVERAGE_FILE = {toxinidir}/.coverage",
26+
]
2427
coverage-command = [
25-
"pytest --cov=src --cov-report=html []",
28+
"coverage erase",
29+
"pytest --cov=src --cov-report= -vs []",
2630
]
2731

2832
[coverage]
2933
fail-under = 98
3034

35+
[coverage-run]
36+
additional-config = [
37+
"parallel = true",
38+
]
39+
3140
[flake8]
3241
additional-config = [
3342
"# E501 line too long",
@@ -37,6 +46,7 @@ additional-config = [
3746

3847
[manifest]
3948
additional-rules = [
49+
"include *.py",
4050
"include *.yaml",
4151
"include pytest.ini",
4252
"recursive-include src *.txt",

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repos:
1212
- id: autopep8
1313
args: [--in-place, --aggressive, --aggressive]
1414
- repo: https://github.com/asottile/pyupgrade
15-
rev: v3.21.0
15+
rev: v3.21.2
1616
hooks:
1717
- id: pyupgrade
1818
args: [--py310-plus]

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ recursive-include docs *.rst
1212
recursive-include docs Makefile
1313

1414
recursive-include src *.py
15+
include *.py
1516
include *.yaml
1617
include pytest.ini
1718
recursive-include src *.txt

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Generated with zope.meta (https://zopemeta.readthedocs.io/) from:
22
# https://github.com/zopefoundation/meta/tree/master/src/zope/meta/pure-python
3-
#
3+
#
44
# Generated from:
55
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
66

@@ -14,6 +14,7 @@ build-backend = "setuptools.build_meta"
1414
[tool.coverage.run]
1515
branch = true
1616
source = ["zope.pytestlayer"]
17+
parallel = true
1718

1819
[tool.coverage.report]
1920
fail_under = 98

sitecustomize.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Coverage sitecustomize - enable coverage for subprocess started via
3+
subprocess.Popen
4+
"""
5+
import atexit
6+
import os
7+
8+
9+
# Check if coverage subprocess tracking is enabled
10+
if 'COVERAGE_PROCESS_START' in os.environ:
11+
import coverage
12+
13+
# Start coverage in this subprocess
14+
cov = coverage.Coverage(
15+
config_file=os.environ['COVERAGE_PROCESS_START'])
16+
cov.start()
17+
atexit.register(cov.save)

src/zope/pytestlayer/_compat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
def _searchbases(cls, accum):
33
# Simulate the "classic class" search order.
44
if cls in accum:
5-
return
5+
return # pragma: no cover
66
accum.append(cls)
77
for base in cls.__bases__:
8-
_searchbases(base, accum)
8+
_searchbases(base, accum) # pragma: no cover
99

1010

1111
def getmro(cls):

src/zope/pytestlayer/tests/test_doctest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class Dummy:
55
"""This class has a doctest.
66
77
It tests the workaround for
8-
https://github.com/zope/zope.pytestlayer/issues/4
8+
https://github.com/zopefoundation/zope.pytestlayer/issues/4
99
1010
>>> print('foobar.')
1111
foobar.

src/zope/pytestlayer/tests/test_integration.py

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import os
12
import os.path
3+
import pathlib
24
import re
35
import subprocess
46
import sys
@@ -14,13 +16,16 @@
1416
(r'\.py::(test_suite)::/', r'.py <- \1: /'),
1517
(r'\.py::(test)', r'.py:NN: \1'),
1618
(r'\.py::(.*Test)::', r'.py:NN: \1.'),
17-
# Compatibility with pytest >= 7.3 which adds this line:
1819
(r'configfile: pytest.ini', ''),
20+
(r'cachedir:.*\n', ''),
21+
(r'rootdir:.*\n', ''),
1922
# With pytest >= 3.3.0 progress is reported after a test result.
2023
# matches [NNN%], [ NN%] and [ N%]
2124
(r'PASSED \[\s*\d{1,3}%\]', 'PASSED'),
22-
# needed to omit all other loaded plugins.
23-
(r'plugins:.*(zope.pytestlayer).*\n', 'plugins: zope.pytestlayer\n'),
25+
# Omit coverage warnings:
26+
(r'.*CoverageWarning:.*', ''),
27+
(r'.*slug="module-not-measured".*', ''),
28+
(r'.*slug="no-data-collected".*', ''),
2429
]
2530

2631

@@ -44,22 +49,38 @@ def where(request):
4449

4550
def run_pytest(name, *args):
4651
cmd = [
47-
sys.argv[0], '-vs', '-p', 'no:removestalebytecode',
52+
sys.executable, '-m', 'pytest', '-vs', '-p', 'no:removestalebytecode',
4853
'--disable-pytest-warnings',
4954
os.path.join(os.path.dirname(__file__), 'fixture', name),
5055
]
5156
cmd.extend(args)
57+
58+
# Set up environment for coverage in subprocess
59+
env = os.environ.copy()
60+
61+
# If running under coverage, enable subprocess tracking
62+
if 'COVERAGE_FILE' in env:
63+
env['COVERAGE_PROCESS_START'] = 'pyproject.toml'
64+
# Add project root to PYTHONPATH so sitecustomize.py is found
65+
project_root = str(pathlib.Path(__file__).parent.parent.parent.parent)
66+
env['PYTHONPATH'] = project_root + ':' + env.get('PYTHONPATH', '')
67+
else:
68+
# Just make brach coverage happy as this branch is only hit when
69+
# running without coverage
70+
pass # pragma: no cover
71+
5272
process = subprocess.Popen(
5373
cmd,
5474
stdout=subprocess.PIPE,
55-
stderr=subprocess.STDOUT)
75+
stderr=subprocess.STDOUT,
76+
env=env)
5677
output = process.stdout.read().decode('latin-1')
5778
for pattern, replacement in normalizers:
5879
output = re.sub(pattern, replacement, output)
59-
lines = output.splitlines(True)
80+
lines = output.strip().splitlines(True)
6081
# Sometimes the output ends with an escape sequence so omitting them to
6182
# make tests happy:
62-
if lines[-1] == '\x1b[?1034h':
83+
if lines[-1] == '\x1b[?1034h': # pragma: no cover
6384
lines.pop(-1)
6485
return lines
6586

@@ -72,7 +93,6 @@ def join(lines, start=4, end=1):
7293
def test_single_layer(where):
7394
lines = run_pytest('single_layer')
7495
assert """\
75-
plugins: zope.pytestlayer
7696
collecting ... collected 1 item
7797
src/zope/pytestlayer/tests/fixture/single_layer/test_core.py:NN: FooTest.test_dummy single_layer.test_core.FooLayer
7898
Set up single_layer.test_core.FooLayer in N.NNN seconds.
@@ -87,7 +107,6 @@ def test_single_layer(where):
87107
def test_single_layer_with_unattached_base_layer(where):
88108
lines = run_pytest('single_layer_with_unattached_base_layer')
89109
assert """\
90-
plugins: zope.pytestlayer
91110
collecting ... collected 1 item
92111
src/zope/pytestlayer/tests/fixture/single_layer_with_unattached_base_layer/test_core.py:NN: FooTest.test_dummy single_layer_with_unattached_base_layer.test_core.BarLayer
93112
Set up single_layer_with_unattached_base_layer.test_core.BarLayer in N.NNN seconds.
@@ -109,7 +128,6 @@ def test_single_layer_with_unattached_base_layer_select_layer(where):
109128
'single_layer_with_unattached_base_layer', '-k', 'BarLayer'
110129
)
111130
assert """\
112-
plugins: zope.pytestlayer
113131
collecting ... collected 1 item
114132
src/zope/pytestlayer/tests/fixture/single_layer_with_unattached_base_layer/test_core.py:NN: FooTest.test_dummy single_layer_with_unattached_base_layer.test_core.BarLayer
115133
Set up single_layer_with_unattached_base_layer.test_core.BarLayer in N.NNN seconds.
@@ -129,7 +147,6 @@ def test_single_layer_with_unattached_base_layer_select_layer(where):
129147
def test_single_layer_in_two_modules(where):
130148
lines = run_pytest('single_layer_in_two_modules')
131149
assert """\
132-
plugins: zope.pytestlayer
133150
collecting ... collected 2 items
134151
src/zope/pytestlayer/tests/fixture/single_layer_in_two_modules/test_core.py:NN: FooTest.test_dummy single_layer_in_two_modules.test_core.FooLayer
135152
Set up single_layer_in_two_modules.test_core.FooLayer in N.NNN seconds.
@@ -148,7 +165,6 @@ def test_single_layer_in_two_modules(where):
148165
def test_single_layered_suite(where):
149166
lines = run_pytest('single_layered_suite')
150167
assert """\
151-
plugins: zope.pytestlayer
152168
collecting ... collected 1 item
153169
src/zope/pytestlayer/tests/fixture/single_layered_suite/test_core.py <- test_suite: /src/zope/pytestlayer/tests/fixture/single_layered_suite/doctest.txt single_layered_suite.test_core.FooLayer
154170
Set up single_layered_suite.test_core.FooLayer in N.NNN seconds.
@@ -163,7 +179,6 @@ def test_single_layered_suite(where):
163179
def test_shared_with_layered_suite(where):
164180
lines = run_pytest('shared_with_layered_suite')
165181
assert """\
166-
plugins: zope.pytestlayer
167182
collecting ... collected 2 items
168183
src/zope/pytestlayer/tests/fixture/shared_with_layered_suite/test_core.py:NN: FooTest.test_dummy shared_with_layered_suite.test_core.FooLayer
169184
Set up shared_with_layered_suite.test_core.FooLayer in N.NNN seconds.
@@ -182,7 +197,6 @@ def test_shared_with_layered_suite(where):
182197
def test_with_and_without_layer(where):
183198
lines = run_pytest('with_and_without_layer')
184199
assert """\
185-
plugins: zope.pytestlayer
186200
collecting ... collected 2 items
187201
src/zope/pytestlayer/tests/fixture/with_and_without_layer/test_core.py:NN: UnitTest.test_dummy PASSED
188202
src/zope/pytestlayer/tests/fixture/with_and_without_layer/test_core.py:NN: FooTest.test_dummy with_and_without_layer.test_core.FooLayer
@@ -198,7 +212,6 @@ def test_with_and_without_layer(where):
198212
def test_two_dependent_layers(where):
199213
lines = run_pytest('two_dependent_layers')
200214
assert """\
201-
plugins: zope.pytestlayer
202215
collecting ... collected 2 items
203216
src/zope/pytestlayer/tests/fixture/two_dependent_layers/test_core.py:NN: FooTest.test_dummy two_dependent_layers.test_core.FooLayer
204217
Set up two_dependent_layers.test_core.FooLayer in N.NNN seconds.
@@ -221,7 +234,6 @@ def test_two_dependent_layers(where):
221234
def test_two_dependent_layered_suites(where):
222235
lines = run_pytest('two_dependent_layered_suites')
223236
assert """\
224-
plugins: zope.pytestlayer
225237
collecting ... collected 2 items
226238
src/zope/pytestlayer/tests/fixture/two_dependent_layered_suites/test_core.py <- test_suite: /src/zope/pytestlayer/tests/fixture/two_dependent_layered_suites/foo.txt two_dependent_layered_suites.test_core.FooLayer
227239
Set up two_dependent_layered_suites.test_core.FooLayer in N.NNN seconds.
@@ -244,7 +256,6 @@ def test_two_dependent_layered_suites(where):
244256
def test_two_independent_layers(where):
245257
lines = run_pytest('two_independent_layers')
246258
assert """\
247-
plugins: zope.pytestlayer
248259
collecting ... collected 2 items
249260
src/zope/pytestlayer/tests/fixture/two_independent_layers/test_core.py:NN: FooTest.test_dummy two_independent_layers.test_core.FooLayer
250261
Set up two_independent_layers.test_core.FooLayer in N.NNN seconds.
@@ -267,7 +278,6 @@ def test_two_independent_layers(where):
267278
def test_keep_layer_across_test_classes(where):
268279
lines = run_pytest('keep_layer_across_test_classes')
269280
assert """\
270-
plugins: zope.pytestlayer
271281
collecting ... collected 3 items
272282
src/zope/pytestlayer/tests/fixture/keep_layer_across_test_classes/test_core.py:NN: FooTest.test_dummy order_by_layer.test_core.FooLayer
273283
Set up keep_layer_across_test_classes.test_core.FooLayer in N.NNN seconds.
@@ -292,13 +302,12 @@ def test_keep_layer_across_test_classes(where):
292302
testTearDown bar
293303
Tear down keep_layer_across_test_classes.test_core.BarLayer in N.NNN seconds.
294304
""" == join(lines)
295-
assert '=== 3 passed' in lines[-1]
305+
assert '=== 3 passed' in lines[-1] # pragma: no cover
296306

297307

298308
def test_order_by_layer(where):
299309
lines = run_pytest('order_by_layer')
300310
assert """\
301-
plugins: zope.pytestlayer
302311
collecting ... collected 4 items
303312
src/zope/pytestlayer/tests/fixture/order_by_layer/test_core.py:NN: FooTest.test_dummy order_by_layer.test_core.FooLayer
304313
Set up order_by_layer.test_core.FooLayer in N.NNN seconds.
@@ -336,7 +345,6 @@ def test_order_by_layer(where):
336345
def test_order_with_layered_suite(where):
337346
lines = run_pytest('order_with_layered_suite')
338347
assert """\
339-
plugins: zope.pytestlayer
340348
collecting ... collected 6 items
341349
src/zope/pytestlayer/tests/fixture/order_with_layered_suite/test_core.py:NN: FooTest.test_dummy order_with_layered_suite.test_core.FooLayer
342350
Set up order_with_layered_suite.test_core.FooLayer in N.NNN seconds.
@@ -386,7 +394,6 @@ def test_order_with_layered_suite(where):
386394
def test_order_with_layered_suite_select_layer(where):
387395
lines = run_pytest('order_with_layered_suite', '-k', 'FooLayer')
388396
assert """\
389-
plugins: zope.pytestlayer
390397
collecting ... collected 6 items / 2 deselected / 4 selected
391398
src/zope/pytestlayer/tests/fixture/order_with_layered_suite/test_core.py:NN: FooTest.test_dummy order_with_layered_suite.test_core.FooLayer
392399
Set up order_with_layered_suite.test_core.FooLayer in N.NNN seconds.
@@ -426,7 +433,6 @@ def test_order_with_layered_suite_select_layer(where):
426433
def test_order_with_layered_suite_select_doctest(where):
427434
lines = run_pytest('order_with_layered_suite', '-k', 'foobar and txt')
428435
assert """\
429-
plugins: zope.pytestlayer
430436
collecting ... collected 6 items / 5 deselected / 1 selected
431437
src/zope/pytestlayer/tests/fixture/order_with_layered_suite/test_core.py <- test_suite: /src/zope/pytestlayer/tests/fixture/order_with_layered_suite/foobar.txt order_with_layered_suite.test_core.FooLayer
432438
Set up order_with_layered_suite.test_core.FooLayer in N.NNN seconds.
@@ -451,7 +457,6 @@ def test_order_with_layered_suite_select_doctest(where):
451457
def test_works_even_without_any_setup_or_teardown_methods(where):
452458
lines = run_pytest('no_setup_or_teardown')
453459
assert """\
454-
plugins: zope.pytestlayer
455460
collecting ... collected 1 item
456461
src/zope/pytestlayer/tests/fixture/no_setup_or_teardown/test_core.py:NN: FooTest.test_dummy PASSED
457462
""" == join(lines)
@@ -469,7 +474,6 @@ def test_nice_error_message_if_layer_has_no_bases(where):
469474
def test_creating_different_fixtures_for_layers_with_the_same_name(where):
470475
lines = run_pytest('layers_with_same_name')
471476
assert """\
472-
plugins: zope.pytestlayer
473477
collecting ... collected 2 items
474478
src/zope/pytestlayer/tests/fixture/layers_with_same_name/test_core.py:NN: FooTest.test_dummy layers_with_same_name.test_core.TestLayer
475479
Set up layers_with_same_name.test_core.TestLayer in N.NNN seconds.
@@ -491,7 +495,6 @@ def test_selection_of_doctest_names(where):
491495
def test_fixture_create_allows_overriding_names(where):
492496
lines = run_pytest('custom_fixture_name')
493497
assert """\
494-
plugins: zope.pytestlayer
495498
collecting ... collected 2 items
496499
src/zope/pytestlayer/tests/fixture/custom_fixture_name/test_core.py:NN: test_can_access_layer_via_fixture custom_fixture_name.test_core.FooLayer
497500
Set up custom_fixture_name.test_core.FooLayer in N.NNN seconds.
@@ -510,7 +513,6 @@ def test_fixture_create_allows_overriding_names(where):
510513
def test_if_session_fixture_is_used_class_fixtures_are_ignored(where):
511514
lines = run_pytest('session_fixture')
512515
assert """\
513-
plugins: zope.pytestlayer
514516
collecting ... collected 2 items
515517
src/zope/pytestlayer/tests/fixture/session_fixture/test_core.py:NN: test_can_access_layer_via_fixture session_fixture.test_core.FooLayer
516518
Set up session_fixture.test_core.FooLayer in N.NNN seconds.

tox.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ deps =
8383
pytest
8484
pytest-cov
8585
pytest-remove-stale-bytecode
86+
setenv =
87+
COVERAGE_FILE = {toxinidir}/.coverage
8688
commands =
8789
mkdir -p {toxinidir}/parts/htmlcov
88-
pytest --cov=src --cov-report=html []
90+
coverage erase
91+
pytest --cov=src --cov-report= -vs []
8992
coverage html
9093
coverage report

0 commit comments

Comments
 (0)