Skip to content

Commit

Permalink
Fix handling when tests change working directory.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ionelmc committed Oct 1, 2015
1 parent 399db61 commit a14e746
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
16 changes: 11 additions & 5 deletions src/pytest_cov/embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ def init():

cov_source = os.environ.get('COV_CORE_SOURCE')
cov_config = os.environ.get('COV_CORE_CONFIG')
if cov_config:
cov_datafile = os.environ.get('COV_CORE_DATAFILE')
if cov_datafile:
# Import what we need to activate coverage.
import coverage

Expand All @@ -50,12 +51,17 @@ def init():
cov_source = None
else:
cov_source = cov_source.split(os.pathsep)
if not cov_config:
cov_config = True

# Activate coverage for this process.
cov = coverage.coverage(source=cov_source,
data_suffix=True,
config_file=cov_config,
auto_data=True)
cov = coverage.coverage(
source=cov_source,
data_suffix=True,
config_file=cov_config,
auto_data=True,
data_file=cov_datafile
)
cov.load()
cov.start()
cov._warn_no_data = False
Expand Down
11 changes: 9 additions & 2 deletions src/pytest_cov/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ def set_env(self):
if self.cov_source is None:
os.environ['COV_CORE_SOURCE'] = ''
else:
os.environ['COV_CORE_SOURCE'] = os.pathsep.join(self.cov_source)
os.environ['COV_CORE_CONFIG'] = self.cov_config
os.environ['COV_CORE_SOURCE'] = os.pathsep.join(
os.path.abspath(p) for p in self.cov_source)
config_file = os.path.abspath(self.cov_config)
if os.path.exists(config_file):
os.environ['COV_CORE_CONFIG'] = config_file
else:
os.environ['COV_CORE_CONFIG'] = ''
os.environ['COV_CORE_DATAFILE'] = os.path.abspath('.coverage')

@staticmethod
def unset_env():
"""Remove coverage info from env."""
os.environ.pop('COV_CORE_SOURCE', None)
os.environ.pop('COV_CORE_CONFIG', None)
os.environ.pop('COV_CORE_DATAFILE', None)

@staticmethod
def get_node_desc(platform, version_info):
Expand Down
50 changes: 49 additions & 1 deletion tests/test_pytest_cov.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import coverage
import py
import pytest

import virtualenv
from process_tests import TestProcess
from process_tests import dump_on_error
from process_tests import wait_for_strings

import pytest_cov.plugin

coverage, StrictVersion # required for skipif mark on test_cov_min_from_coveragerc
Expand Down Expand Up @@ -75,6 +75,30 @@ def test_foo(idx):
pass
'''

SCRIPT_PARENT_CHANGE_CWD = '''
import subprocess
import sys
import os
def pytest_generate_tests(metafunc):
for i in range(2):
metafunc.addcall(funcargs=dict(idx=i))
def test_foo(idx):
os.mkdir("foobar")
os.chdir("foobar")
subprocess.check_call([
sys.executable,
os.path.join(os.path.dirname(__file__), 'child_script.py'),
str(idx)
])
# there is a issue in coverage.py with multiline statements at
# end of file: https://bitbucket.org/ned/coveragepy/issue/293
pass
'''

SCRIPT_FUNCARG = '''
import coverage
Expand Down Expand Up @@ -350,6 +374,30 @@ def test_central_subprocess(testdir):
assert result.ret == 0


def test_central_subprocess_change_cwd(testdir):
scripts = testdir.makepyfile(parent_script=SCRIPT_PARENT_CHANGE_CWD,
child_script=SCRIPT_CHILD)
parent_script = scripts.dirpath().join('parent_script.py')
testdir.makefile('', coveragerc="""
[run]
branch = true
parallel = true
""")

result = testdir.runpytest('-v', '--tb=short',
'--cov=%s' % scripts.dirpath(),
'--cov-config=coveragerc',
'--cov-report=term-missing',
parent_script)

result.stdout.fnmatch_lines([
'*- coverage: platform *, python * -*',
'child_script* %s *' % CHILD_SCRIPT_RESULT,
'parent_script* 100% *',
])
assert result.ret == 0


def test_central_subprocess_no_subscript(testdir):
script = testdir.makepyfile("""
import subprocess, sys
Expand Down

0 comments on commit a14e746

Please sign in to comment.