Merged in issue616 (pull request #252)
fix issue616 - conftest visibility fixes.
This commit is contained in:
commit
1e6e373913
14
CHANGELOG
14
CHANGELOG
|
@ -1,6 +1,20 @@
|
|||
2.7.0.dev (compared to 2.6.4)
|
||||
-----------------------------
|
||||
|
||||
- fix issue616: conftest.py files and their contained fixutres are now
|
||||
properly considered for visibility, independently from the exact
|
||||
current working directory and test arguments that are used.
|
||||
Many thanks to Eric Siegerman and his PR235 which contains
|
||||
systematic tests for conftest visibility and now passes.
|
||||
This change also introduces the concept of a ``rootdir`` which
|
||||
is printed as a new pytest header and documented in the pytest
|
||||
customize web page.
|
||||
|
||||
- change reporting of "diverted" tests, i.e. tests that are collected
|
||||
in one file but actually come from another (e.g. when tests in a test class
|
||||
come from a base class in a different file). We now show the nodeid
|
||||
and indicate via a postfix the other file.
|
||||
|
||||
- add ability to set command line options by environment variable PYTEST_ADDOPTS.
|
||||
|
||||
- added documentation on the new pytest-dev teams on bitbucket and
|
||||
|
|
|
@ -657,6 +657,12 @@ class Config(object):
|
|||
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
||||
sys.stderr.flush()
|
||||
|
||||
def cwd_relative_nodeid(self, nodeid):
|
||||
# nodeid's are relative to the rootpath, compute relative to cwd
|
||||
if self.invocation_dir != self.rootdir:
|
||||
fullpath = self.rootdir.join(nodeid)
|
||||
nodeid = self.invocation_dir.bestrelpath(fullpath)
|
||||
return nodeid
|
||||
|
||||
@classmethod
|
||||
def fromdictargs(cls, option_dict, args):
|
||||
|
@ -691,14 +697,9 @@ class Config(object):
|
|||
|
||||
def _initini(self, args):
|
||||
parsed_args = self._parser.parse_known_args(args)
|
||||
if parsed_args.inifilename:
|
||||
iniconfig = py.iniconfig.IniConfig(parsed_args.inifilename)
|
||||
if 'pytest' in iniconfig.sections:
|
||||
self.inicfg = iniconfig['pytest']
|
||||
else:
|
||||
self.inicfg = {}
|
||||
else:
|
||||
self.inicfg = getcfg(args, ["pytest.ini", "tox.ini", "setup.cfg"])
|
||||
r = determine_setup(parsed_args.inifilename, parsed_args.file_or_dir)
|
||||
self.rootdir, self.inifile, self.inicfg = r
|
||||
self.invocation_dir = py.path.local()
|
||||
self._parser.addini('addopts', 'extra command line options', 'args')
|
||||
self._parser.addini('minversion', 'minimally required pytest version')
|
||||
|
||||
|
@ -859,8 +860,58 @@ def getcfg(args, inibasenames):
|
|||
if exists(p):
|
||||
iniconfig = py.iniconfig.IniConfig(p)
|
||||
if 'pytest' in iniconfig.sections:
|
||||
return iniconfig['pytest']
|
||||
return {}
|
||||
return base, p, iniconfig['pytest']
|
||||
elif inibasename == "pytest.ini":
|
||||
# allowed to be empty
|
||||
return base, p, {}
|
||||
return None, None, None
|
||||
|
||||
|
||||
def get_common_ancestor(args):
|
||||
# args are what we get after early command line parsing (usually
|
||||
# strings, but can be py.path.local objects as well)
|
||||
common_ancestor = None
|
||||
for arg in args:
|
||||
if str(arg)[0] == "-":
|
||||
continue
|
||||
p = py.path.local(arg)
|
||||
if common_ancestor is None:
|
||||
common_ancestor = p
|
||||
else:
|
||||
if p.relto(common_ancestor) or p == common_ancestor:
|
||||
continue
|
||||
elif common_ancestor.relto(p):
|
||||
common_ancestor = p
|
||||
else:
|
||||
shared = p.common(common_ancestor)
|
||||
if shared is not None:
|
||||
common_ancestor = shared
|
||||
if common_ancestor is None:
|
||||
common_ancestor = py.path.local()
|
||||
elif not common_ancestor.isdir():
|
||||
common_ancestor = common_ancestor.dirpath()
|
||||
return common_ancestor
|
||||
|
||||
|
||||
def determine_setup(inifile, args):
|
||||
if inifile:
|
||||
iniconfig = py.iniconfig.IniConfig(inifile)
|
||||
try:
|
||||
inicfg = iniconfig["pytest"]
|
||||
except KeyError:
|
||||
inicfg = None
|
||||
rootdir = get_common_ancestor(args)
|
||||
else:
|
||||
ancestor = get_common_ancestor(args)
|
||||
rootdir, inifile, inicfg = getcfg(
|
||||
[ancestor], ["pytest.ini", "tox.ini", "setup.cfg"])
|
||||
if rootdir is None:
|
||||
for rootdir in ancestor.parts(reverse=True):
|
||||
if rootdir.join("setup.py").exists():
|
||||
break
|
||||
else:
|
||||
rootdir = ancestor
|
||||
return rootdir, inifile, inicfg or {}
|
||||
|
||||
|
||||
def setns(obj, dic):
|
||||
|
|
|
@ -457,9 +457,7 @@ class FSCollector(Collector):
|
|||
self.fspath = fspath
|
||||
|
||||
def _makeid(self):
|
||||
if self == self.session:
|
||||
return "."
|
||||
relpath = self.session.fspath.bestrelpath(self.fspath)
|
||||
relpath = self.fspath.relto(self.config.rootdir)
|
||||
if os.sep != "/":
|
||||
relpath = relpath.replace(os.sep, "/")
|
||||
return relpath
|
||||
|
@ -510,7 +508,7 @@ class Session(FSCollector):
|
|||
__module__ = 'builtins' # for py3
|
||||
|
||||
def __init__(self, config):
|
||||
FSCollector.__init__(self, py.path.local(), parent=None,
|
||||
FSCollector.__init__(self, config.rootdir, parent=None,
|
||||
config=config, session=self)
|
||||
self.config.pluginmanager.register(self, name="session", prepend=True)
|
||||
self._testsfailed = 0
|
||||
|
@ -520,6 +518,9 @@ class Session(FSCollector):
|
|||
self.startdir = py.path.local()
|
||||
self._fs2hookproxy = {}
|
||||
|
||||
def _makeid(self):
|
||||
return ""
|
||||
|
||||
def pytest_collectstart(self):
|
||||
if self.shouldstop:
|
||||
raise self.Interrupted(self.shouldstop)
|
||||
|
@ -663,7 +664,7 @@ class Session(FSCollector):
|
|||
arg = self._tryconvertpyarg(arg)
|
||||
parts = str(arg).split("::")
|
||||
relpath = parts[0].replace("/", os.sep)
|
||||
path = self.fspath.join(relpath, abs=True)
|
||||
path = self.config.invocation_dir.join(relpath, abs=True)
|
||||
if not path.check():
|
||||
if self.config.option.pyargs:
|
||||
msg = "file or package not found: "
|
||||
|
|
|
@ -306,9 +306,8 @@ class TmpTestdir:
|
|||
session = Session(config)
|
||||
assert '::' not in str(arg)
|
||||
p = py.path.local(arg)
|
||||
x = session.fspath.bestrelpath(p)
|
||||
config.hook.pytest_sessionstart(session=session)
|
||||
res = session.perform_collect([x], genitems=False)[0]
|
||||
res = session.perform_collect([str(p)], genitems=False)[0]
|
||||
config.hook.pytest_sessionfinish(session=session, exitstatus=EXIT_OK)
|
||||
return res
|
||||
|
||||
|
@ -395,8 +394,7 @@ class TmpTestdir:
|
|||
def parseconfigure(self, *args):
|
||||
config = self.parseconfig(*args)
|
||||
config.do_configure()
|
||||
self.request.addfinalizer(lambda:
|
||||
config.do_unconfigure())
|
||||
self.request.addfinalizer(config.do_unconfigure)
|
||||
return config
|
||||
|
||||
def getitem(self, source, funcname="test_func"):
|
||||
|
|
|
@ -1653,11 +1653,9 @@ class FixtureManager:
|
|||
# what fixtures are visible for particular tests (as denoted
|
||||
# by their test id)
|
||||
if p.basename.startswith("conftest.py"):
|
||||
nodeid = self.session.fspath.bestrelpath(p.dirpath())
|
||||
nodeid = p.dirpath().relto(self.config.rootdir)
|
||||
if p.sep != "/":
|
||||
nodeid = nodeid.replace(p.sep, "/")
|
||||
if nodeid == ".":
|
||||
nodeid = ""
|
||||
self.parsefactories(plugin, nodeid)
|
||||
self._seenplugins.add(plugin)
|
||||
|
||||
|
|
|
@ -218,14 +218,14 @@ def show_simple(terminalreporter, lines, stat, format):
|
|||
failed = terminalreporter.stats.get(stat)
|
||||
if failed:
|
||||
for rep in failed:
|
||||
pos = rep.nodeid
|
||||
lines.append(format %(pos, ))
|
||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||
lines.append(format %(pos,))
|
||||
|
||||
def show_xfailed(terminalreporter, lines):
|
||||
xfailed = terminalreporter.stats.get("xfailed")
|
||||
if xfailed:
|
||||
for rep in xfailed:
|
||||
pos = rep.nodeid
|
||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||
reason = rep.wasxfail
|
||||
lines.append("XFAIL %s" % (pos,))
|
||||
if reason:
|
||||
|
@ -235,7 +235,7 @@ def show_xpassed(terminalreporter, lines):
|
|||
xpassed = terminalreporter.stats.get("xpassed")
|
||||
if xpassed:
|
||||
for rep in xpassed:
|
||||
pos = rep.nodeid
|
||||
pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
|
||||
reason = rep.wasxfail
|
||||
lines.append("XPASS %s %s" %(pos, reason))
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class TerminalReporter:
|
|||
self._numcollected = 0
|
||||
|
||||
self.stats = {}
|
||||
self.startdir = self.curdir = py.path.local()
|
||||
self.startdir = py.path.local()
|
||||
if file is None:
|
||||
file = sys.stdout
|
||||
self._tw = self.writer = py.io.TerminalWriter(file)
|
||||
|
@ -111,12 +111,12 @@ class TerminalReporter:
|
|||
char = {'xfailed': 'x', 'skipped': 's'}.get(char, char)
|
||||
return char in self.reportchars
|
||||
|
||||
def write_fspath_result(self, fspath, res):
|
||||
def write_fspath_result(self, nodeid, res):
|
||||
fspath = self.config.rootdir.join(nodeid.split("::")[0])
|
||||
if fspath != self.currentfspath:
|
||||
self.currentfspath = fspath
|
||||
#fspath = self.startdir.bestrelpath(fspath)
|
||||
fspath = self.startdir.bestrelpath(fspath)
|
||||
self._tw.line()
|
||||
#relpath = self.startdir.bestrelpath(fspath)
|
||||
self._tw.write(fspath + " ")
|
||||
self._tw.write(res)
|
||||
|
||||
|
@ -182,12 +182,12 @@ class TerminalReporter:
|
|||
def pytest_runtest_logstart(self, nodeid, location):
|
||||
# ensure that the path is printed before the
|
||||
# 1st test of a module starts running
|
||||
fspath = nodeid.split("::")[0]
|
||||
if self.showlongtestinfo:
|
||||
line = self._locationline(fspath, *location)
|
||||
line = self._locationline(nodeid, *location)
|
||||
self.write_ensure_prefix(line, "")
|
||||
elif self.showfspath:
|
||||
self.write_fspath_result(fspath, "")
|
||||
fsid = nodeid.split("::")[0]
|
||||
self.write_fspath_result(fsid, "")
|
||||
|
||||
def pytest_runtest_logreport(self, report):
|
||||
rep = report
|
||||
|
@ -200,7 +200,7 @@ class TerminalReporter:
|
|||
return
|
||||
if self.verbosity <= 0:
|
||||
if not hasattr(rep, 'node') and self.showfspath:
|
||||
self.write_fspath_result(rep.fspath, letter)
|
||||
self.write_fspath_result(rep.nodeid, letter)
|
||||
else:
|
||||
self._tw.write(letter)
|
||||
else:
|
||||
|
@ -213,7 +213,7 @@ class TerminalReporter:
|
|||
markup = {'red':True}
|
||||
elif rep.skipped:
|
||||
markup = {'yellow':True}
|
||||
line = self._locationline(str(rep.fspath), *rep.location)
|
||||
line = self._locationline(rep.nodeid, *rep.location)
|
||||
if not hasattr(rep, 'node'):
|
||||
self.write_ensure_prefix(line, word, **markup)
|
||||
#self._tw.write(word, **markup)
|
||||
|
@ -237,7 +237,7 @@ class TerminalReporter:
|
|||
items = [x for x in report.result if isinstance(x, pytest.Item)]
|
||||
self._numcollected += len(items)
|
||||
if self.hasmarkup:
|
||||
#self.write_fspath_result(report.fspath, 'E')
|
||||
#self.write_fspath_result(report.nodeid, 'E')
|
||||
self.report_collect()
|
||||
|
||||
def report_collect(self, final=False):
|
||||
|
@ -288,6 +288,10 @@ class TerminalReporter:
|
|||
self.write_line(line)
|
||||
|
||||
def pytest_report_header(self, config):
|
||||
inifile = ""
|
||||
if config.inifile:
|
||||
inifile = config.rootdir.bestrelpath(config.inifile)
|
||||
lines = ["rootdir: %s, inifile: %s" %(config.rootdir, inifile)]
|
||||
plugininfo = config.pluginmanager._plugin_distinfo
|
||||
if plugininfo:
|
||||
l = []
|
||||
|
@ -296,7 +300,8 @@ class TerminalReporter:
|
|||
if name.startswith("pytest-"):
|
||||
name = name[7:]
|
||||
l.append(name)
|
||||
return "plugins: %s" % ", ".join(l)
|
||||
lines.append("plugins: %s" % ", ".join(l))
|
||||
return lines
|
||||
|
||||
def pytest_collection_finish(self, session):
|
||||
if self.config.option.collectonly:
|
||||
|
@ -378,19 +383,24 @@ class TerminalReporter:
|
|||
else:
|
||||
excrepr.reprcrash.toterminal(self._tw)
|
||||
|
||||
def _locationline(self, collect_fspath, fspath, lineno, domain):
|
||||
def _locationline(self, nodeid, fspath, lineno, domain):
|
||||
def mkrel(nodeid):
|
||||
line = self.config.cwd_relative_nodeid(nodeid)
|
||||
if domain and line.endswith(domain):
|
||||
line = line[:-len(domain)]
|
||||
l = domain.split("[")
|
||||
l[0] = l[0].replace('.', '::') # don't replace '.' in params
|
||||
line += "[".join(l)
|
||||
return line
|
||||
# collect_fspath comes from testid which has a "/"-normalized path
|
||||
if fspath and fspath.replace("\\", "/") != collect_fspath:
|
||||
fspath = "%s <- %s" % (collect_fspath, fspath)
|
||||
|
||||
if fspath:
|
||||
line = str(fspath)
|
||||
if domain:
|
||||
split = str(domain).split('[')
|
||||
split[0] = split[0].replace('.', '::') # don't replace '.' in params
|
||||
line += "::" + '['.join(split)
|
||||
res = mkrel(nodeid).replace("::()", "") # parens-normalization
|
||||
if nodeid.split("::")[0] != fspath.replace("\\", "/"):
|
||||
res += " <- " + self.startdir.bestrelpath(fspath)
|
||||
else:
|
||||
line = "[location]"
|
||||
return line + " "
|
||||
res = "[location]"
|
||||
return res + " "
|
||||
|
||||
def _getfailureheadline(self, rep):
|
||||
if hasattr(rep, 'location'):
|
||||
|
|
|
@ -12,37 +12,73 @@ configurations files by using the general help option::
|
|||
This will display command line and configuration file settings
|
||||
which were registered by installed plugins.
|
||||
|
||||
.. _rootdir:
|
||||
.. _inifiles:
|
||||
|
||||
How test configuration is read from configuration INI-files
|
||||
-------------------------------------------------------------
|
||||
initialization: determining rootdir and inifile
|
||||
-----------------------------------------------
|
||||
|
||||
``pytest`` searches for the first matching ini-style configuration file
|
||||
in the directories of command line argument and the directories above.
|
||||
It looks for file basenames in this order::
|
||||
.. versionadded:: 2.7
|
||||
|
||||
pytest determines a "rootdir" for each test run which depends on
|
||||
the command line arguments (specified test files, paths) and on
|
||||
the existence of inifiles. The determined rootdir and ini-file are
|
||||
printed as part of the pytest header. The rootdir is used for constructing
|
||||
"nodeids" during collection and may also be used by plugins to store
|
||||
project/testrun-specific information.
|
||||
|
||||
Here is the algorithm which finds the rootdir from ``args``:
|
||||
|
||||
- determine the common ancestor directory for the specified ``args``.
|
||||
|
||||
- look for ``pytest.ini``, ``tox.ini`` and ``setup.cfg`` files in the
|
||||
ancestor directory and upwards. If one is matched, it becomes the
|
||||
ini-file and its directory becomes the rootdir. An existing
|
||||
``pytest.ini`` file will always be considered a match whereas
|
||||
``tox.ini`` and ``setup.cfg`` will only match if they contain
|
||||
a ``[pytest]`` section.
|
||||
|
||||
- if no ini-file was found, look for ``setup.py`` upwards from
|
||||
the common ancestor directory to determine the ``rootdir``.
|
||||
|
||||
- if no ini-file and no ``setup.py`` was found, use the already
|
||||
determined common ancestor as root directory. This allows to
|
||||
work with pytest in structures that are not part of a package
|
||||
and don't have any particular ini-file configuration.
|
||||
|
||||
Note that options from multiple ini-files candidates are never merged,
|
||||
the first one wins (``pytest.ini`` always wins even if it does not
|
||||
contain a ``[pytest]`` section).
|
||||
|
||||
The ``config`` object will subsequently carry these attributes:
|
||||
|
||||
- ``config.rootdir``: the determined root directory, guaranteed to exist.
|
||||
|
||||
- ``config.inifile``: the determined ini-file, may be ``None``.
|
||||
|
||||
The rootdir is used a reference directory for constructing test
|
||||
addresses ("nodeids") and can be used also by plugins for storing
|
||||
per-testrun information.
|
||||
|
||||
Example::
|
||||
|
||||
py.test path/to/testdir path/other/
|
||||
|
||||
will determine the common ancestor as ``path`` and then
|
||||
check for ini-files as follows::
|
||||
|
||||
# first look for pytest.ini files
|
||||
path/pytest.ini
|
||||
path/setup.cfg # must also contain [pytest] section to match
|
||||
path/tox.ini # must also contain [pytest] section to match
|
||||
pytest.ini
|
||||
tox.ini
|
||||
setup.cfg
|
||||
... # all the way down to the root
|
||||
|
||||
Searching stops when the first ``[pytest]`` section is found in any of
|
||||
these files. There is no merging of configuration values from multiple
|
||||
files. Example::
|
||||
# now look for setup.py
|
||||
path/setup.py
|
||||
setup.py
|
||||
... # all the way down to the root
|
||||
|
||||
py.test path/to/testdir
|
||||
|
||||
will look in the following dirs for a config file::
|
||||
|
||||
path/to/testdir/pytest.ini
|
||||
path/to/testdir/tox.ini
|
||||
path/to/testdir/setup.cfg
|
||||
path/to/pytest.ini
|
||||
path/to/tox.ini
|
||||
path/to/setup.cfg
|
||||
... # up until root of filesystem
|
||||
|
||||
If argument is provided to a ``pytest`` run, the current working directory
|
||||
is used to start the search.
|
||||
|
||||
.. _`how to change command line options defaults`:
|
||||
.. _`adding default options`:
|
||||
|
@ -67,6 +103,8 @@ line options while the environment is in use::
|
|||
|
||||
From now on, running ``pytest`` will add the specified options.
|
||||
|
||||
|
||||
|
||||
Builtin configuration file options
|
||||
----------------------------------------------
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ class TestSession:
|
|||
("pytest_make_collect_report", "collector.fspath == p"),
|
||||
("pytest_pycollect_makeitem", "name == 'test_func'"),
|
||||
("pytest_collectreport", "report.nodeid.startswith(p.basename)"),
|
||||
("pytest_collectreport", "report.nodeid == '.'")
|
||||
("pytest_collectreport", "report.nodeid == ''")
|
||||
])
|
||||
|
||||
def test_collect_protocol_method(self, testdir):
|
||||
|
@ -478,7 +478,7 @@ class Test_getinitialnodes:
|
|||
config = testdir.parseconfigure(x)
|
||||
col = testdir.getnode(config, x)
|
||||
assert isinstance(col, pytest.Module)
|
||||
assert col.name == 'subdir/x.py'
|
||||
assert col.name == 'x.py'
|
||||
assert col.parent.parent is None
|
||||
for col in col.listchain():
|
||||
assert col.config is config
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import py, pytest
|
||||
|
||||
from _pytest.config import getcfg
|
||||
from _pytest.config import getcfg, get_common_ancestor, determine_setup
|
||||
|
||||
class TestParseIni:
|
||||
def test_getcfg_and_config(self, testdir, tmpdir):
|
||||
|
@ -10,7 +10,7 @@ class TestParseIni:
|
|||
[pytest]
|
||||
name = value
|
||||
"""))
|
||||
cfg = getcfg([sub], ["setup.cfg"])
|
||||
rootdir, inifile, cfg = getcfg([sub], ["setup.cfg"])
|
||||
assert cfg['name'] == "value"
|
||||
config = testdir.parseconfigure(sub)
|
||||
assert config.inicfg['name'] == 'value'
|
||||
|
@ -400,3 +400,55 @@ class TestWarning:
|
|||
*WT1*test_warn_on_test_item*:5*hello*
|
||||
*1 warning*
|
||||
""")
|
||||
|
||||
class TestRootdir:
|
||||
def test_simple_noini(self, tmpdir):
|
||||
assert get_common_ancestor([tmpdir]) == tmpdir
|
||||
assert get_common_ancestor([tmpdir.mkdir("a"), tmpdir]) == tmpdir
|
||||
assert get_common_ancestor([tmpdir, tmpdir.join("a")]) == tmpdir
|
||||
with tmpdir.as_cwd():
|
||||
assert get_common_ancestor([]) == tmpdir
|
||||
|
||||
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
|
||||
def test_with_ini(self, tmpdir, name):
|
||||
inifile = tmpdir.join(name)
|
||||
inifile.write("[pytest]\n")
|
||||
|
||||
a = tmpdir.mkdir("a")
|
||||
b = a.mkdir("b")
|
||||
for args in ([tmpdir], [a], [b]):
|
||||
rootdir, inifile, inicfg = determine_setup(None, args)
|
||||
assert rootdir == tmpdir
|
||||
assert inifile == inifile
|
||||
rootdir, inifile, inicfg = determine_setup(None, [b,a])
|
||||
assert rootdir == tmpdir
|
||||
assert inifile == inifile
|
||||
|
||||
@pytest.mark.parametrize("name", "setup.cfg tox.ini".split())
|
||||
def test_pytestini_overides_empty_other(self, tmpdir, name):
|
||||
inifile = tmpdir.ensure("pytest.ini")
|
||||
a = tmpdir.mkdir("a")
|
||||
a.ensure(name)
|
||||
rootdir, inifile, inicfg = determine_setup(None, [a])
|
||||
assert rootdir == tmpdir
|
||||
assert inifile == inifile
|
||||
|
||||
def test_setuppy_fallback(self, tmpdir):
|
||||
a = tmpdir.mkdir("a")
|
||||
a.ensure("setup.cfg")
|
||||
tmpdir.ensure("setup.py")
|
||||
rootdir, inifile, inicfg = determine_setup(None, [a])
|
||||
assert rootdir == tmpdir
|
||||
assert inifile is None
|
||||
assert inicfg == {}
|
||||
|
||||
def test_nothing(self, tmpdir):
|
||||
rootdir, inifile, inicfg = determine_setup(None, [tmpdir])
|
||||
assert rootdir == tmpdir
|
||||
assert inifile is None
|
||||
assert inicfg == {}
|
||||
|
||||
def test_with_specific_inifile(self, tmpdir):
|
||||
inifile = tmpdir.ensure("pytest.ini")
|
||||
rootdir, inifile, inicfg = determine_setup(inifile, [tmpdir])
|
||||
assert rootdir == tmpdir
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
from textwrap import dedent
|
||||
import py, pytest
|
||||
from _pytest.config import Conftest
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", params=["global", "inpackage"])
|
||||
def basedir(request):
|
||||
from _pytest.tmpdir import tmpdir
|
||||
|
@ -255,3 +257,89 @@ def test_conftest_found_with_double_dash(testdir):
|
|||
result.stdout.fnmatch_lines("""
|
||||
*--hello-world*
|
||||
""")
|
||||
|
||||
|
||||
class TestConftestVisibility:
|
||||
def _setup_tree(self, testdir): # for issue616
|
||||
# example mostly taken from:
|
||||
# https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html
|
||||
runner = testdir.mkdir("empty")
|
||||
package = testdir.mkdir("package")
|
||||
|
||||
package.join("conftest.py").write(dedent("""\
|
||||
import pytest
|
||||
@pytest.fixture
|
||||
def fxtr():
|
||||
return "from-package"
|
||||
"""))
|
||||
package.join("test_pkgroot.py").write(dedent("""\
|
||||
def test_pkgroot(fxtr):
|
||||
assert fxtr == "from-package"
|
||||
"""))
|
||||
|
||||
swc = package.mkdir("swc")
|
||||
swc.join("__init__.py").ensure()
|
||||
swc.join("conftest.py").write(dedent("""\
|
||||
import pytest
|
||||
@pytest.fixture
|
||||
def fxtr():
|
||||
return "from-swc"
|
||||
"""))
|
||||
swc.join("test_with_conftest.py").write(dedent("""\
|
||||
def test_with_conftest(fxtr):
|
||||
assert fxtr == "from-swc"
|
||||
|
||||
"""))
|
||||
|
||||
snc = package.mkdir("snc")
|
||||
snc.join("__init__.py").ensure()
|
||||
snc.join("test_no_conftest.py").write(dedent("""\
|
||||
def test_no_conftest(fxtr):
|
||||
assert fxtr == "from-package" # No local conftest.py, so should
|
||||
# use value from parent dir's
|
||||
|
||||
"""))
|
||||
print ("created directory structure:")
|
||||
for x in testdir.tmpdir.visit():
|
||||
print (" " + x.relto(testdir.tmpdir))
|
||||
|
||||
return {
|
||||
"runner": runner,
|
||||
"package": package,
|
||||
"swc": swc,
|
||||
"snc": snc}
|
||||
|
||||
# N.B.: "swc" stands for "subdir with conftest.py"
|
||||
# "snc" stands for "subdir no [i.e. without] conftest.py"
|
||||
@pytest.mark.parametrize("chdir,testarg,expect_ntests_passed", [
|
||||
("runner", "..", 3),
|
||||
("package", "..", 3),
|
||||
("swc", "../..", 3),
|
||||
("snc", "../..", 3),
|
||||
|
||||
("runner", "../package", 3),
|
||||
("package", ".", 3),
|
||||
("swc", "..", 3),
|
||||
("snc", "..", 3),
|
||||
|
||||
("runner", "../package/swc", 1),
|
||||
("package", "./swc", 1),
|
||||
("swc", ".", 1),
|
||||
("snc", "../swc", 1),
|
||||
|
||||
("runner", "../package/snc", 1),
|
||||
("package", "./snc", 1),
|
||||
("swc", "../snc", 1),
|
||||
("snc", ".", 1),
|
||||
])
|
||||
@pytest.mark.issue616
|
||||
def test_parsefactories_relative_node_ids(
|
||||
self, testdir, chdir,testarg, expect_ntests_passed):
|
||||
dirs = self._setup_tree(testdir)
|
||||
print("pytest run in cwd: %s" %(
|
||||
dirs[chdir].relto(testdir.tmpdir)))
|
||||
print("pytestarg : %s" %(testarg))
|
||||
print("expected pass : %s" %(expect_ntests_passed))
|
||||
with dirs[chdir].as_cwd():
|
||||
reprec = testdir.inline_run(testarg, "-q", "--traceconfig")
|
||||
reprec.assertoutcome(passed=expect_ntests_passed)
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile
|
||||
import py, pytest
|
||||
|
||||
import pdb
|
||||
|
||||
|
||||
class TestDoctests:
|
||||
|
||||
def test_collect_testtextfile(self, testdir):
|
||||
|
|
|
@ -77,11 +77,11 @@ class TestTerminal:
|
|||
def test_writeline(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol("def test_one(): pass")
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
rep.write_fspath_result(py.path.local("xy.py"), '.')
|
||||
rep.write_fspath_result(modcol.nodeid, ".")
|
||||
rep.write_line("hello world")
|
||||
lines = linecomp.stringio.getvalue().split('\n')
|
||||
assert not lines[0]
|
||||
assert lines[1].endswith("xy.py .")
|
||||
assert lines[1].endswith(modcol.name + " .")
|
||||
assert lines[2] == "hello world"
|
||||
|
||||
def test_show_runtest_logstart(self, testdir, linecomp):
|
||||
|
@ -126,7 +126,7 @@ class TestTerminal:
|
|||
])
|
||||
result = testdir.runpytest("-v", p2)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_p2.py <- *test_p1.py::TestMore::test_p1*",
|
||||
"*test_p2.py::TestMore::test_p1* <- *test_p1.py*PASSED",
|
||||
])
|
||||
|
||||
def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir):
|
||||
|
|
Loading…
Reference in New Issue