[Pytest-commit] commit/pytest: hpk42: fix issue436: improved finding of initial conftest files from command
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Wed Apr 2 11:52:54 CEST 2014
1 new commit in pytest:
https://bitbucket.org/hpk42/pytest/commits/083d8d0b065f/
Changeset: 083d8d0b065f
User: hpk42
Date: 2014-04-02 11:29:23
Summary: fix issue436: improved finding of initial conftest files from command
line arguments by using the result of parse_known_args rather than
the previous flaky heuristics. Thanks Marc Abramowitz for tests
and initial fixing approaches in this area.
Affected #: 5 files
diff -r 8d04808c1e928179c11974741428a418a9378d37 -r 083d8d0b065f11860fc1ec4edb50480b6ee50b35 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,11 @@
- change skips into warnings for test classes with an __init__ and
callables in test modules which look like a test but are not functions.
+- fix issue436: improved finding of initial conftest files from command
+ line arguments by using the result of parse_known_args rather than
+ the previous flaky heuristics. Thanks Marc Abramowitz for tests
+ and initial fixing approaches in this area.
+
- fix issue #479: properly handle nose/unittest(2) SkipTest exceptions
during collection/loading of test modules. Thanks to Marc Schlaich
for the complete PR.
diff -r 8d04808c1e928179c11974741428a418a9378d37 -r 083d8d0b065f11860fc1ec4edb50480b6ee50b35 _pytest/capture.py
--- a/_pytest/capture.py
+++ b/_pytest/capture.py
@@ -31,7 +31,7 @@
@pytest.mark.tryfirst
def pytest_load_initial_conftests(early_config, parser, args, __multicall__):
- ns = parser.parse_known_args(args)
+ ns = early_config.known_args_namespace
pluginmanager = early_config.pluginmanager
if ns.capture == "no":
return
diff -r 8d04808c1e928179c11974741428a418a9378d37 -r 083d8d0b065f11860fc1ec4edb50480b6ee50b35 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -449,38 +449,27 @@
""" the single place for accessing values and interacting
towards conftest modules from pytest objects.
"""
- def __init__(self, onimport=None, confcutdir=None):
+ def __init__(self, onimport=None):
self._path2confmods = {}
self._onimport = onimport
self._conftestpath2mod = {}
- self._confcutdir = confcutdir
+ self._confcutdir = None
- def setinitial(self, args):
- """ try to find a first anchor path for looking up global values
- from conftests. This function is usually called _before_
- argument parsing. conftest files may add command line options
- and we thus have no completely safe way of determining
- which parts of the arguments are actually related to options
- and which are file system paths. We just try here to get
- bootstrapped ...
+ def setinitial(self, namespace):
+ """ load initial conftest files given a preparsed "namespace".
+ As conftest files may add their own command line options
+ which have arguments ('--my-opt somepath') we might get some
+ false positives. All builtin and 3rd party plugins will have
+ been loaded, however, so common options will not confuse our logic
+ here.
"""
current = py.path.local()
- opt = '--confcutdir'
- for i in range(len(args)):
- opt1 = str(args[i])
- if opt1.startswith(opt):
- if opt1 == opt:
- if len(args) > i:
- p = current.join(args[i+1], abs=True)
- elif opt1.startswith(opt + "="):
- p = current.join(opt1[len(opt)+1:], abs=1)
- self._confcutdir = p
- break
+ self._confcutdir = current.join(namespace.confcutdir, abs=True) \
+ if namespace.confcutdir else None
+ testpaths = namespace.file_or_dir
foundanchor = False
- for arg in args:
- if hasattr(arg, 'startswith') and arg.startswith("--"):
- continue
- anchor = current.join(arg, abs=1)
+ for path in testpaths:
+ anchor = current.join(path, abs=1)
if exists(anchor): # we found some file object
self._try_load_conftest(anchor)
foundanchor = True
@@ -676,8 +665,8 @@
plugins += self._conftest.getconftestmodules(fspath)
return plugins
- def pytest_load_initial_conftests(self, parser, args):
- self._conftest.setinitial(args)
+ def pytest_load_initial_conftests(self, early_config):
+ self._conftest.setinitial(early_config.known_args_namespace)
pytest_load_initial_conftests.trylast = True
def _initini(self, args):
@@ -693,6 +682,7 @@
self.pluginmanager.consider_preparse(args)
self.pluginmanager.consider_setuptools_entrypoints()
self.pluginmanager.consider_env()
+ self.known_args_namespace = self._parser.parse_known_args(args)
self.hook.pytest_load_initial_conftests(early_config=self,
args=args, parser=self._parser)
@@ -710,7 +700,6 @@
def parse(self, args):
# parse given cmdline arguments into this config object.
- # Note that this can only be called once per testing process.
assert not hasattr(self, 'args'), (
"can only parse cmdline args at most once per Config object")
self._origargs = args
diff -r 8d04808c1e928179c11974741428a418a9378d37 -r 083d8d0b065f11860fc1ec4edb50480b6ee50b35 testing/test_config.py
--- a/testing/test_config.py
+++ b/testing/test_config.py
@@ -148,7 +148,7 @@
assert config.getvalue('x') == 1
config.option.x = 2
assert config.getvalue('x') == 2
- config = testdir.parseconfig([str(o)])
+ config = testdir.parseconfig(str(o))
assert config.getvalue('x') == 1
def test_getconftest_pathlist(self, testdir, tmpdir):
diff -r 8d04808c1e928179c11974741428a418a9378d37 -r 083d8d0b065f11860fc1ec4edb50480b6ee50b35 testing/test_conftest.py
--- a/testing/test_conftest.py
+++ b/testing/test_conftest.py
@@ -20,19 +20,26 @@
def ConftestWithSetinitial(path):
conftest = Conftest()
- conftest.setinitial([path])
+ conftest_setinitial(conftest, [path])
return conftest
+def conftest_setinitial(conftest, args, confcutdir=None):
+ class Namespace:
+ def __init__(self):
+ self.file_or_dir = args
+ self.confcutdir = str(confcutdir)
+ conftest.setinitial(Namespace())
+
class TestConftestValueAccessGlobal:
def test_basic_init(self, basedir):
conftest = Conftest()
- conftest.setinitial([basedir.join("adir")])
+ conftest_setinitial(conftest, [basedir.join("adir")])
assert conftest.rget("a") == 1
def test_onimport(self, basedir):
l = []
conftest = Conftest(onimport=l.append)
- conftest.setinitial([basedir.join("adir"),
+ conftest_setinitial(conftest, [basedir.join("adir"),
'--confcutdir=%s' % basedir])
assert len(l) == 1
assert conftest.rget("a") == 1
@@ -99,13 +106,13 @@
tmpdir.ensure("adir-1.0/__init__.py")
ConftestWithSetinitial(tmpdir.join("adir-1.0", "b"))
-def test_doubledash_not_considered(testdir):
+def test_doubledash_considered(testdir):
conf = testdir.mkdir("--option")
conf.join("conftest.py").ensure()
conftest = Conftest()
- conftest.setinitial([conf.basename, conf.basename])
+ conftest_setinitial(conftest, [conf.basename, conf.basename])
l = conftest.getconftestmodules(None)
- assert len(l) == 0
+ assert len(l) == 1
def test_issue151_load_all_conftests(testdir):
names = "code proj src".split()
@@ -114,7 +121,7 @@
p.ensure("conftest.py")
conftest = Conftest()
- conftest.setinitial(names)
+ conftest_setinitial(conftest, names)
d = list(conftest._conftestpath2mod.values())
assert len(d) == len(names)
@@ -142,8 +149,8 @@
def test_conftestcutdir(testdir):
conf = testdir.makeconftest("")
p = testdir.mkdir("x")
- conftest = Conftest(confcutdir=p)
- conftest.setinitial([testdir.tmpdir])
+ conftest = Conftest()
+ conftest_setinitial(conftest, [testdir.tmpdir], confcutdir=p)
l = conftest.getconftestmodules(p)
assert len(l) == 0
l = conftest.getconftestmodules(conf.dirpath())
@@ -160,34 +167,18 @@
def test_conftestcutdir_inplace_considered(testdir):
conf = testdir.makeconftest("")
- conftest = Conftest(confcutdir=conf.dirpath())
- conftest.setinitial([conf.dirpath()])
+ conftest = Conftest()
+ conftest_setinitial(conftest, [conf.dirpath()], confcutdir=conf.dirpath())
l = conftest.getconftestmodules(conf.dirpath())
assert len(l) == 1
assert l[0].__file__.startswith(str(conf))
-def test_setinitial_confcut(testdir):
- conf = testdir.makeconftest("")
- sub = testdir.mkdir("sub")
- sub.chdir()
- for opts in (["--confcutdir=%s" % sub, sub],
- [sub, "--confcutdir=%s" % sub],
- ["--confcutdir=.", sub],
- [sub, "--confcutdir", sub],
- [str(sub), "--confcutdir", "."],
- ):
- conftest = Conftest()
- conftest.setinitial(opts)
- assert conftest._confcutdir == sub
- assert conftest.getconftestmodules(sub) == []
- assert conftest.getconftestmodules(conf.dirpath()) == []
-
@pytest.mark.parametrize("name", 'test tests whatever .dotdir'.split())
def test_setinitial_conftest_subdirs(testdir, name):
sub = testdir.mkdir(name)
subconftest = sub.ensure("conftest.py")
conftest = Conftest()
- conftest.setinitial([sub.dirpath(), '--confcutdir=%s' % testdir.tmpdir])
+ conftest_setinitial(conftest, [sub.dirpath()], confcutdir=testdir.tmpdir)
if name not in ('whatever', '.dotdir'):
assert subconftest in conftest._conftestpath2mod
assert len(conftest._conftestpath2mod) == 1
@@ -205,6 +196,26 @@
result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
result.stdout.fnmatch_lines(["*--xyz*"])
+def test_conftest_existing_resultlog(testdir):
+ x = testdir.mkdir("tests")
+ x.join("conftest.py").write(py.code.Source("""
+ def pytest_addoption(parser):
+ parser.addoption("--xyz", action="store_true")
+ """))
+ testdir.makefile(ext=".log", result="") # Writes result.log
+ result = testdir.runpytest("-h", "--resultlog", "result.log")
+ result.stdout.fnmatch_lines(["*--xyz*"])
+
+def test_conftest_existing_junitxml(testdir):
+ x = testdir.mkdir("tests")
+ x.join("conftest.py").write(py.code.Source("""
+ def pytest_addoption(parser):
+ parser.addoption("--xyz", action="store_true")
+ """))
+ testdir.makefile(ext=".xml", junit="") # Writes junit.xml
+ result = testdir.runpytest("-h", "--junitxml", "junit.xml")
+ result.stdout.fnmatch_lines(["*--xyz*"])
+
def test_conftest_import_order(testdir, monkeypatch):
ct1 = testdir.makeconftest("")
sub = testdir.mkdir("sub")
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list