Skip to content

Commit a14e746

Browse files
committed
Fix handling when tests change working directory.
Use absolute paths for coverage config file and sources. Add a new internal variable "COV_CORE_DATAFILE" to workaround the misplacement of .coverage.foobar.123 files. Because needs to be an absolute path COV_CORE_CONFIG we need to do some special things: coverage treats config_file='.coveragerc' as if it was config_file=True. We need to keep that behavior. Closes #94. Closes #77.
1 parent 399db61 commit a14e746

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

src/pytest_cov/embed.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ def init():
4141

4242
cov_source = os.environ.get('COV_CORE_SOURCE')
4343
cov_config = os.environ.get('COV_CORE_CONFIG')
44-
if cov_config:
44+
cov_datafile = os.environ.get('COV_CORE_DATAFILE')
45+
if cov_datafile:
4546
# Import what we need to activate coverage.
4647
import coverage
4748

@@ -50,12 +51,17 @@ def init():
5051
cov_source = None
5152
else:
5253
cov_source = cov_source.split(os.pathsep)
54+
if not cov_config:
55+
cov_config = True
5356

5457
# Activate coverage for this process.
55-
cov = coverage.coverage(source=cov_source,
56-
data_suffix=True,
57-
config_file=cov_config,
58-
auto_data=True)
58+
cov = coverage.coverage(
59+
source=cov_source,
60+
data_suffix=True,
61+
config_file=cov_config,
62+
auto_data=True,
63+
data_file=cov_datafile
64+
)
5965
cov.load()
6066
cov.start()
6167
cov._warn_no_data = False

src/pytest_cov/engine.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,21 @@ def set_env(self):
3434
if self.cov_source is None:
3535
os.environ['COV_CORE_SOURCE'] = ''
3636
else:
37-
os.environ['COV_CORE_SOURCE'] = os.pathsep.join(self.cov_source)
38-
os.environ['COV_CORE_CONFIG'] = self.cov_config
37+
os.environ['COV_CORE_SOURCE'] = os.pathsep.join(
38+
os.path.abspath(p) for p in self.cov_source)
39+
config_file = os.path.abspath(self.cov_config)
40+
if os.path.exists(config_file):
41+
os.environ['COV_CORE_CONFIG'] = config_file
42+
else:
43+
os.environ['COV_CORE_CONFIG'] = ''
44+
os.environ['COV_CORE_DATAFILE'] = os.path.abspath('.coverage')
3945

4046
@staticmethod
4147
def unset_env():
4248
"""Remove coverage info from env."""
4349
os.environ.pop('COV_CORE_SOURCE', None)
4450
os.environ.pop('COV_CORE_CONFIG', None)
51+
os.environ.pop('COV_CORE_DATAFILE', None)
4552

4653
@staticmethod
4754
def get_node_desc(platform, version_info):

tests/test_pytest_cov.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import coverage
88
import py
99
import pytest
10-
1110
import virtualenv
1211
from process_tests import TestProcess
1312
from process_tests import dump_on_error
1413
from process_tests import wait_for_strings
14+
1515
import pytest_cov.plugin
1616

1717
coverage, StrictVersion # required for skipif mark on test_cov_min_from_coveragerc
@@ -75,6 +75,30 @@ def test_foo(idx):
7575
pass
7676
'''
7777

78+
SCRIPT_PARENT_CHANGE_CWD = '''
79+
import subprocess
80+
import sys
81+
import os
82+
83+
def pytest_generate_tests(metafunc):
84+
for i in range(2):
85+
metafunc.addcall(funcargs=dict(idx=i))
86+
87+
def test_foo(idx):
88+
os.mkdir("foobar")
89+
os.chdir("foobar")
90+
91+
subprocess.check_call([
92+
sys.executable,
93+
os.path.join(os.path.dirname(__file__), 'child_script.py'),
94+
str(idx)
95+
])
96+
97+
# there is a issue in coverage.py with multiline statements at
98+
# end of file: https://bitbucket.org/ned/coveragepy/issue/293
99+
pass
100+
'''
101+
78102
SCRIPT_FUNCARG = '''
79103
import coverage
80104
@@ -350,6 +374,30 @@ def test_central_subprocess(testdir):
350374
assert result.ret == 0
351375

352376

377+
def test_central_subprocess_change_cwd(testdir):
378+
scripts = testdir.makepyfile(parent_script=SCRIPT_PARENT_CHANGE_CWD,
379+
child_script=SCRIPT_CHILD)
380+
parent_script = scripts.dirpath().join('parent_script.py')
381+
testdir.makefile('', coveragerc="""
382+
[run]
383+
branch = true
384+
parallel = true
385+
""")
386+
387+
result = testdir.runpytest('-v', '--tb=short',
388+
'--cov=%s' % scripts.dirpath(),
389+
'--cov-config=coveragerc',
390+
'--cov-report=term-missing',
391+
parent_script)
392+
393+
result.stdout.fnmatch_lines([
394+
'*- coverage: platform *, python * -*',
395+
'child_script* %s *' % CHILD_SCRIPT_RESULT,
396+
'parent_script* 100% *',
397+
])
398+
assert result.ret == 0
399+
400+
353401
def test_central_subprocess_no_subscript(testdir):
354402
script = testdir.makepyfile("""
355403
import subprocess, sys

0 commit comments

Comments
 (0)