2019-09-12 07:09:08 +08:00
|
|
|
import os
|
2018-08-24 00:06:17 +08:00
|
|
|
import textwrap
|
2015-11-27 22:43:01 +08:00
|
|
|
|
|
|
|
import py
|
2018-10-25 15:01:29 +08:00
|
|
|
|
2015-11-27 22:43:01 +08:00
|
|
|
import pytest
|
2020-02-11 05:43:30 +08:00
|
|
|
from _pytest.config import ExitCode
|
2019-08-27 22:16:45 +08:00
|
|
|
from _pytest.config import PytestPluginManager
|
2019-11-15 10:53:05 +08:00
|
|
|
from _pytest.pathlib import Path
|
2020-06-08 21:56:40 +08:00
|
|
|
from _pytest.pathlib import symlink_or_skip
|
2009-05-19 00:59:45 +08:00
|
|
|
|
2015-02-27 04:56:44 +08:00
|
|
|
|
2009-12-29 00:49:46 +08:00
|
|
|
def ConftestWithSetinitial(path):
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, [path])
|
2009-12-29 00:49:46 +08:00
|
|
|
return conftest
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-04-02 17:29:23 +08:00
|
|
|
def conftest_setinitial(conftest, args, confcutdir=None):
|
2019-06-03 06:32:00 +08:00
|
|
|
class Namespace:
|
2014-04-02 17:29:23 +08:00
|
|
|
def __init__(self):
|
|
|
|
self.file_or_dir = args
|
|
|
|
self.confcutdir = str(confcutdir)
|
2015-06-23 13:53:32 +08:00
|
|
|
self.noconftest = False
|
2018-09-26 23:00:49 +08:00
|
|
|
self.pyargs = False
|
2020-06-13 22:29:01 +08:00
|
|
|
self.importmode = "prepend"
|
2018-05-23 22:48:46 +08:00
|
|
|
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest._set_initial_conftests(Namespace())
|
2014-04-02 17:29:23 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2019-04-05 17:31:02 +08:00
|
|
|
@pytest.mark.usefixtures("_sys_snapshot")
|
2019-06-03 06:32:00 +08:00
|
|
|
class TestConftestValueAccessGlobal:
|
2019-04-04 23:07:15 +08:00
|
|
|
@pytest.fixture(scope="module", params=["global", "inpackage"])
|
|
|
|
def basedir(self, request, tmpdir_factory):
|
|
|
|
tmpdir = tmpdir_factory.mktemp("basedir", numbered=True)
|
|
|
|
tmpdir.ensure("adir/conftest.py").write("a=1 ; Directory = 3")
|
|
|
|
tmpdir.ensure("adir/b/conftest.py").write("b=2 ; a = 1.5")
|
|
|
|
if request.param == "inpackage":
|
|
|
|
tmpdir.ensure("adir/__init__.py")
|
|
|
|
tmpdir.ensure("adir/b/__init__.py")
|
|
|
|
|
|
|
|
yield tmpdir
|
|
|
|
|
2009-05-19 00:59:45 +08:00
|
|
|
def test_basic_init(self, basedir):
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-03 04:30:45 +08:00
|
|
|
p = basedir.join("adir")
|
2020-06-13 22:29:01 +08:00
|
|
|
assert conftest._rget_with_confmod("a", p, importmode="prepend")[1] == 1
|
2009-02-27 18:18:27 +08:00
|
|
|
|
2009-05-19 00:59:45 +08:00
|
|
|
def test_immediate_initialiation_and_incremental_are_the_same(self, basedir):
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2019-04-05 16:59:08 +08:00
|
|
|
assert not len(conftest._dirpath2confmods)
|
2020-06-13 22:29:01 +08:00
|
|
|
conftest._getconftestmodules(basedir, importmode="prepend")
|
2018-10-25 00:50:59 +08:00
|
|
|
snap1 = len(conftest._dirpath2confmods)
|
2019-04-05 16:59:08 +08:00
|
|
|
assert snap1 == 1
|
2020-06-13 22:29:01 +08:00
|
|
|
conftest._getconftestmodules(basedir.join("adir"), importmode="prepend")
|
2018-10-25 00:50:59 +08:00
|
|
|
assert len(conftest._dirpath2confmods) == snap1 + 1
|
2020-06-13 22:29:01 +08:00
|
|
|
conftest._getconftestmodules(basedir.join("b"), importmode="prepend")
|
2018-10-25 00:50:59 +08:00
|
|
|
assert len(conftest._dirpath2confmods) == snap1 + 2
|
2008-08-16 23:26:59 +08:00
|
|
|
|
2009-05-19 00:59:45 +08:00
|
|
|
def test_value_access_not_existing(self, basedir):
|
2009-12-29 00:49:46 +08:00
|
|
|
conftest = ConftestWithSetinitial(basedir)
|
2014-04-03 04:30:45 +08:00
|
|
|
with pytest.raises(KeyError):
|
2020-06-13 22:29:01 +08:00
|
|
|
conftest._rget_with_confmod("a", basedir, importmode="prepend")
|
2008-08-16 23:26:59 +08:00
|
|
|
|
2009-05-19 00:59:45 +08:00
|
|
|
def test_value_access_by_path(self, basedir):
|
2009-12-29 00:49:46 +08:00
|
|
|
conftest = ConftestWithSetinitial(basedir)
|
2014-04-03 04:30:45 +08:00
|
|
|
adir = basedir.join("adir")
|
2020-06-13 22:29:01 +08:00
|
|
|
assert conftest._rget_with_confmod("a", adir, importmode="prepend")[1] == 1
|
|
|
|
assert (
|
|
|
|
conftest._rget_with_confmod("a", adir.join("b"), importmode="prepend")[1]
|
|
|
|
== 1.5
|
|
|
|
)
|
2008-08-16 23:26:59 +08:00
|
|
|
|
2009-05-19 00:59:45 +08:00
|
|
|
def test_value_access_with_confmod(self, basedir):
|
2010-09-15 16:30:50 +08:00
|
|
|
startdir = basedir.join("adir", "b")
|
|
|
|
startdir.ensure("xx", dir=True)
|
|
|
|
conftest = ConftestWithSetinitial(startdir)
|
2020-06-13 22:29:01 +08:00
|
|
|
mod, value = conftest._rget_with_confmod("a", startdir, importmode="prepend")
|
2017-07-17 07:25:09 +08:00
|
|
|
assert value == 1.5
|
2008-08-16 23:26:59 +08:00
|
|
|
path = py.path.local(mod.__file__)
|
2009-05-19 00:59:45 +08:00
|
|
|
assert path.dirpath() == basedir.join("adir", "b")
|
2011-09-21 14:12:37 +08:00
|
|
|
assert path.purebasename.startswith("conftest")
|
2009-12-31 22:10:32 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2019-04-05 17:31:02 +08:00
|
|
|
def test_conftest_in_nonpkg_with_init(tmpdir, _sys_snapshot):
|
2010-04-27 21:49:13 +08:00
|
|
|
tmpdir.ensure("adir-1.0/conftest.py").write("a=1 ; Directory = 3")
|
|
|
|
tmpdir.ensure("adir-1.0/b/conftest.py").write("b=2 ; a = 1.5")
|
|
|
|
tmpdir.ensure("adir-1.0/b/__init__.py")
|
|
|
|
tmpdir.ensure("adir-1.0/__init__.py")
|
2013-10-12 21:39:22 +08:00
|
|
|
ConftestWithSetinitial(tmpdir.join("adir-1.0", "b"))
|
2010-04-27 21:49:13 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-04-02 17:29:23 +08:00
|
|
|
def test_doubledash_considered(testdir):
|
2010-07-02 01:27:40 +08:00
|
|
|
conf = testdir.mkdir("--option")
|
2017-12-01 20:28:39 +08:00
|
|
|
conf.ensure("conftest.py")
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, [conf.basename, conf.basename])
|
2020-06-13 22:29:01 +08:00
|
|
|
values = conftest._getconftestmodules(conf, importmode="prepend")
|
2017-11-04 23:17:20 +08:00
|
|
|
assert len(values) == 1
|
2010-07-02 01:27:40 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2012-06-27 03:56:03 +08:00
|
|
|
def test_issue151_load_all_conftests(testdir):
|
|
|
|
names = "code proj src".split()
|
|
|
|
for name in names:
|
|
|
|
p = testdir.mkdir(name)
|
|
|
|
p.ensure("conftest.py")
|
|
|
|
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, names)
|
2012-06-27 03:56:03 +08:00
|
|
|
d = list(conftest._conftestpath2mod.values())
|
|
|
|
assert len(d) == len(names)
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2010-10-14 00:45:07 +08:00
|
|
|
def test_conftest_global_import(testdir):
|
|
|
|
testdir.makeconftest("x=3")
|
2018-05-23 22:48:46 +08:00
|
|
|
p = testdir.makepyfile(
|
|
|
|
"""
|
2010-11-18 05:12:16 +08:00
|
|
|
import py, pytest
|
2015-04-22 20:15:42 +08:00
|
|
|
from _pytest.config import PytestPluginManager
|
|
|
|
conf = PytestPluginManager()
|
2020-06-13 22:29:01 +08:00
|
|
|
mod = conf._importconftest(py.path.local("conftest.py"), importmode="prepend")
|
2010-10-14 00:45:07 +08:00
|
|
|
assert mod.x == 3
|
|
|
|
import conftest
|
|
|
|
assert conftest is mod, (conftest, mod)
|
|
|
|
subconf = py.path.local().ensure("sub", "conftest.py")
|
|
|
|
subconf.write("y=4")
|
2020-06-13 22:29:01 +08:00
|
|
|
mod2 = conf._importconftest(subconf, importmode="prepend")
|
2010-10-14 00:45:07 +08:00
|
|
|
assert mod != mod2
|
|
|
|
assert mod2.y == 4
|
|
|
|
import conftest
|
|
|
|
assert conftest is mod2, (conftest, mod)
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2010-10-14 00:45:07 +08:00
|
|
|
res = testdir.runpython(p)
|
|
|
|
assert res.ret == 0
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2009-12-31 22:10:32 +08:00
|
|
|
def test_conftestcutdir(testdir):
|
|
|
|
conf = testdir.makeconftest("")
|
|
|
|
p = testdir.mkdir("x")
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, [testdir.tmpdir], confcutdir=p)
|
2020-06-13 22:29:01 +08:00
|
|
|
values = conftest._getconftestmodules(p, importmode="prepend")
|
2017-11-04 23:17:20 +08:00
|
|
|
assert len(values) == 0
|
2020-06-13 22:29:01 +08:00
|
|
|
values = conftest._getconftestmodules(conf.dirpath(), importmode="prepend")
|
2017-11-04 23:17:20 +08:00
|
|
|
assert len(values) == 0
|
2009-12-31 22:10:32 +08:00
|
|
|
assert conf not in conftest._conftestpath2mod
|
2010-07-27 03:15:15 +08:00
|
|
|
# but we can still import a conftest directly
|
2020-06-13 22:29:01 +08:00
|
|
|
conftest._importconftest(conf, importmode="prepend")
|
|
|
|
values = conftest._getconftestmodules(conf.dirpath(), importmode="prepend")
|
2019-09-12 06:37:42 +08:00
|
|
|
assert values[0].__file__.startswith(str(conf))
|
2009-12-31 22:10:32 +08:00
|
|
|
# and all sub paths get updated properly
|
2020-06-13 22:29:01 +08:00
|
|
|
values = conftest._getconftestmodules(p, importmode="prepend")
|
2017-11-04 23:17:20 +08:00
|
|
|
assert len(values) == 1
|
2019-09-12 06:37:42 +08:00
|
|
|
assert values[0].__file__.startswith(str(conf))
|
2009-12-31 22:10:32 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2009-12-31 22:10:32 +08:00
|
|
|
def test_conftestcutdir_inplace_considered(testdir):
|
|
|
|
conf = testdir.makeconftest("")
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, [conf.dirpath()], confcutdir=conf.dirpath())
|
2020-06-13 22:29:01 +08:00
|
|
|
values = conftest._getconftestmodules(conf.dirpath(), importmode="prepend")
|
2017-11-04 23:17:20 +08:00
|
|
|
assert len(values) == 1
|
2019-09-12 06:37:42 +08:00
|
|
|
assert values[0].__file__.startswith(str(conf))
|
2009-12-31 22:10:32 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
@pytest.mark.parametrize("name", "test tests whatever .dotdir".split())
|
2010-02-07 05:37:04 +08:00
|
|
|
def test_setinitial_conftest_subdirs(testdir, name):
|
2010-02-04 19:26:53 +08:00
|
|
|
sub = testdir.mkdir(name)
|
|
|
|
subconftest = sub.ensure("conftest.py")
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2014-04-02 17:29:23 +08:00
|
|
|
conftest_setinitial(conftest, [sub.dirpath()], confcutdir=testdir.tmpdir)
|
2019-09-12 07:09:08 +08:00
|
|
|
key = Path(str(subconftest)).resolve()
|
2018-05-23 22:48:46 +08:00
|
|
|
if name not in ("whatever", ".dotdir"):
|
2019-09-12 07:09:08 +08:00
|
|
|
assert key in conftest._conftestpath2mod
|
2010-02-07 05:37:04 +08:00
|
|
|
assert len(conftest._conftestpath2mod) == 1
|
|
|
|
else:
|
2019-09-12 07:09:08 +08:00
|
|
|
assert key not in conftest._conftestpath2mod
|
2010-02-07 05:37:04 +08:00
|
|
|
assert len(conftest._conftestpath2mod) == 0
|
2010-10-10 19:48:48 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2010-10-10 19:48:48 +08:00
|
|
|
def test_conftest_confcutdir(testdir):
|
|
|
|
testdir.makeconftest("assert 0")
|
|
|
|
x = testdir.mkdir("x")
|
2018-05-23 22:48:46 +08:00
|
|
|
x.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--xyz", action="store_true")
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2010-10-10 19:48:48 +08:00
|
|
|
result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
|
|
|
|
result.stdout.fnmatch_lines(["*--xyz*"])
|
2019-10-06 01:18:51 +08:00
|
|
|
result.stdout.no_fnmatch_line("*warning: could not load initial*")
|
2013-04-18 19:24:53 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2018-10-10 22:56:18 +08:00
|
|
|
def test_conftest_symlink(testdir):
|
2020-06-08 21:56:40 +08:00
|
|
|
"""
|
|
|
|
conftest.py discovery follows normal path resolution and does not resolve symlinks.
|
|
|
|
"""
|
|
|
|
# Structure:
|
|
|
|
# /real
|
|
|
|
# /real/conftest.py
|
|
|
|
# /real/app
|
|
|
|
# /real/app/tests
|
|
|
|
# /real/app/tests/test_foo.py
|
|
|
|
|
|
|
|
# Links:
|
|
|
|
# /symlinktests -> /real/app/tests (running at symlinktests should fail)
|
|
|
|
# /symlink -> /real (running at /symlink should work)
|
|
|
|
|
2018-10-22 19:57:01 +08:00
|
|
|
real = testdir.tmpdir.mkdir("real")
|
|
|
|
realtests = real.mkdir("app").mkdir("tests")
|
2020-06-08 21:56:40 +08:00
|
|
|
symlink_or_skip(realtests, testdir.tmpdir.join("symlinktests"))
|
|
|
|
symlink_or_skip(real, testdir.tmpdir.join("symlink"))
|
2018-10-10 22:56:18 +08:00
|
|
|
testdir.makepyfile(
|
|
|
|
**{
|
|
|
|
"real/app/tests/test_foo.py": "def test1(fixture): pass",
|
|
|
|
"real/conftest.py": textwrap.dedent(
|
|
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
print("conftest_loaded")
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def fixture():
|
|
|
|
print("fixture_used")
|
|
|
|
"""
|
|
|
|
),
|
|
|
|
}
|
|
|
|
)
|
2020-06-08 21:56:40 +08:00
|
|
|
|
|
|
|
# Should fail because conftest cannot be found from the link structure.
|
2018-10-10 22:56:18 +08:00
|
|
|
result = testdir.runpytest("-vs", "symlinktests")
|
2020-06-08 21:56:40 +08:00
|
|
|
result.stdout.fnmatch_lines(["*fixture 'fixture' not found*"])
|
|
|
|
assert result.ret == ExitCode.TESTS_FAILED
|
2018-10-10 22:56:18 +08:00
|
|
|
|
2018-10-22 19:57:01 +08:00
|
|
|
# Should not cause "ValueError: Plugin already registered" (#4174).
|
|
|
|
result = testdir.runpytest("-vs", "symlink")
|
2019-06-07 18:58:51 +08:00
|
|
|
assert result.ret == ExitCode.OK
|
2018-10-22 19:57:01 +08:00
|
|
|
|
2018-10-10 22:56:18 +08:00
|
|
|
|
2019-02-07 09:04:06 +08:00
|
|
|
def test_conftest_symlink_files(testdir):
|
2020-06-08 21:56:40 +08:00
|
|
|
"""Symlinked conftest.py are found when pytest is executed in a directory with symlinked
|
|
|
|
files."""
|
2019-02-07 09:04:06 +08:00
|
|
|
real = testdir.tmpdir.mkdir("real")
|
|
|
|
source = {
|
|
|
|
"app/test_foo.py": "def test1(fixture): pass",
|
|
|
|
"app/__init__.py": "",
|
|
|
|
"app/conftest.py": textwrap.dedent(
|
|
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
print("conftest_loaded")
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def fixture():
|
|
|
|
print("fixture_used")
|
|
|
|
"""
|
|
|
|
),
|
|
|
|
}
|
|
|
|
testdir.makepyfile(**{"real/%s" % k: v for k, v in source.items()})
|
|
|
|
|
|
|
|
# Create a build directory that contains symlinks to actual files
|
|
|
|
# but doesn't symlink actual directories.
|
|
|
|
build = testdir.tmpdir.mkdir("build")
|
|
|
|
build.mkdir("app")
|
|
|
|
for f in source:
|
2020-06-08 21:56:40 +08:00
|
|
|
symlink_or_skip(real.join(f), build.join(f))
|
2019-02-07 09:04:06 +08:00
|
|
|
build.chdir()
|
|
|
|
result = testdir.runpytest("-vs", "app/test_foo.py")
|
|
|
|
result.stdout.fnmatch_lines(["*conftest_loaded*", "PASSED"])
|
2019-06-07 18:58:51 +08:00
|
|
|
assert result.ret == ExitCode.OK
|
2019-02-07 09:04:06 +08:00
|
|
|
|
2019-08-27 22:16:45 +08:00
|
|
|
|
2019-09-12 07:09:08 +08:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
os.path.normcase("x") != os.path.normcase("X"),
|
|
|
|
reason="only relevant for case insensitive file systems",
|
|
|
|
)
|
|
|
|
def test_conftest_badcase(testdir):
|
|
|
|
"""Check conftest.py loading when directory casing is wrong (#5792)."""
|
|
|
|
testdir.tmpdir.mkdir("JenkinsRoot").mkdir("test")
|
|
|
|
source = {"setup.py": "", "test/__init__.py": "", "test/conftest.py": ""}
|
|
|
|
testdir.makepyfile(**{"JenkinsRoot/%s" % k: v for k, v in source.items()})
|
|
|
|
|
|
|
|
testdir.tmpdir.join("jenkinsroot/test").chdir()
|
|
|
|
result = testdir.runpytest()
|
|
|
|
assert result.ret == ExitCode.NO_TESTS_COLLECTED
|
|
|
|
|
|
|
|
|
|
|
|
def test_conftest_uppercase(testdir):
|
|
|
|
"""Check conftest.py whose qualified name contains uppercase characters (#5819)"""
|
|
|
|
source = {"__init__.py": "", "Foo/conftest.py": "", "Foo/__init__.py": ""}
|
|
|
|
testdir.makepyfile(**source)
|
|
|
|
|
|
|
|
testdir.tmpdir.chdir()
|
|
|
|
result = testdir.runpytest()
|
|
|
|
assert result.ret == ExitCode.NO_TESTS_COLLECTED
|
|
|
|
|
|
|
|
|
2015-06-23 13:53:32 +08:00
|
|
|
def test_no_conftest(testdir):
|
|
|
|
testdir.makeconftest("assert 0")
|
|
|
|
result = testdir.runpytest("--noconftest")
|
2019-06-07 18:58:51 +08:00
|
|
|
assert result.ret == ExitCode.NO_TESTS_COLLECTED
|
2015-07-05 01:42:22 +08:00
|
|
|
|
|
|
|
result = testdir.runpytest()
|
2019-06-07 18:58:51 +08:00
|
|
|
assert result.ret == ExitCode.USAGE_ERROR
|
2015-06-23 13:53:32 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-04-02 17:29:23 +08:00
|
|
|
def test_conftest_existing_resultlog(testdir):
|
|
|
|
x = testdir.mkdir("tests")
|
2018-05-23 22:48:46 +08:00
|
|
|
x.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--xyz", action="store_true")
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2014-04-02 17:29:23 +08:00
|
|
|
testdir.makefile(ext=".log", result="") # Writes result.log
|
|
|
|
result = testdir.runpytest("-h", "--resultlog", "result.log")
|
|
|
|
result.stdout.fnmatch_lines(["*--xyz*"])
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-04-02 17:29:23 +08:00
|
|
|
def test_conftest_existing_junitxml(testdir):
|
|
|
|
x = testdir.mkdir("tests")
|
2018-05-23 22:48:46 +08:00
|
|
|
x.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--xyz", action="store_true")
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2014-04-02 17:29:23 +08:00
|
|
|
testdir.makefile(ext=".xml", junit="") # Writes junit.xml
|
|
|
|
result = testdir.runpytest("-h", "--junitxml", "junit.xml")
|
|
|
|
result.stdout.fnmatch_lines(["*--xyz*"])
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2013-04-18 19:24:53 +08:00
|
|
|
def test_conftest_import_order(testdir, monkeypatch):
|
|
|
|
ct1 = testdir.makeconftest("")
|
|
|
|
sub = testdir.mkdir("sub")
|
|
|
|
ct2 = sub.join("conftest.py")
|
|
|
|
ct2.write("")
|
2016-11-21 04:59:15 +08:00
|
|
|
|
2020-06-13 22:29:01 +08:00
|
|
|
def impct(p, importmode):
|
2013-04-18 19:24:53 +08:00
|
|
|
return p
|
2016-11-21 04:59:15 +08:00
|
|
|
|
2015-04-22 20:15:42 +08:00
|
|
|
conftest = PytestPluginManager()
|
2016-07-14 15:14:19 +08:00
|
|
|
conftest._confcutdir = testdir.tmpdir
|
2018-05-23 22:48:46 +08:00
|
|
|
monkeypatch.setattr(conftest, "_importconftest", impct)
|
2020-06-13 22:29:01 +08:00
|
|
|
assert conftest._getconftestmodules(sub, importmode="prepend") == [ct1, ct2]
|
2013-11-12 20:45:36 +08:00
|
|
|
|
|
|
|
|
2020-01-17 02:42:29 +08:00
|
|
|
def test_fixture_dependency(testdir):
|
2013-11-12 20:45:36 +08:00
|
|
|
ct1 = testdir.makeconftest("")
|
|
|
|
ct1 = testdir.makepyfile("__init__.py")
|
|
|
|
ct1.write("")
|
|
|
|
sub = testdir.mkdir("sub")
|
|
|
|
sub.join("__init__.py").write("")
|
2018-05-23 22:48:46 +08:00
|
|
|
sub.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
import pytest
|
2013-11-12 20:45:36 +08:00
|
|
|
|
2018-08-24 00:06:17 +08:00
|
|
|
@pytest.fixture
|
|
|
|
def not_needed():
|
|
|
|
assert False, "Should not be called!"
|
2013-11-12 20:45:36 +08:00
|
|
|
|
2018-08-24 00:06:17 +08:00
|
|
|
@pytest.fixture
|
|
|
|
def foo():
|
|
|
|
assert False, "Should not be called!"
|
2013-11-12 20:45:36 +08:00
|
|
|
|
2018-08-24 00:06:17 +08:00
|
|
|
@pytest.fixture
|
|
|
|
def bar(foo):
|
|
|
|
return 'bar'
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
2013-11-12 20:45:36 +08:00
|
|
|
subsub = sub.mkdir("subsub")
|
|
|
|
subsub.join("__init__.py").write("")
|
2018-05-23 22:48:46 +08:00
|
|
|
subsub.join("test_bar.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
import pytest
|
2013-11-12 20:45:36 +08:00
|
|
|
|
2018-08-24 00:06:17 +08:00
|
|
|
@pytest.fixture
|
|
|
|
def bar():
|
|
|
|
return 'sub bar'
|
2013-11-12 20:45:36 +08:00
|
|
|
|
2018-08-24 00:06:17 +08:00
|
|
|
def test_event_fixture(bar):
|
|
|
|
assert bar == 'sub bar'
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
2013-11-12 20:45:36 +08:00
|
|
|
result = testdir.runpytest("sub")
|
|
|
|
result.stdout.fnmatch_lines(["*1 passed*"])
|
2014-07-28 17:48:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
def test_conftest_found_with_double_dash(testdir):
|
|
|
|
sub = testdir.mkdir("sub")
|
2018-05-23 22:48:46 +08:00
|
|
|
sub.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--hello-world", action="store_true")
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2014-07-28 17:48:37 +08:00
|
|
|
p = sub.join("test_hello.py")
|
2017-12-11 22:10:04 +08:00
|
|
|
p.write("def test_hello(): pass")
|
2014-08-01 07:29:35 +08:00
|
|
|
result = testdir.runpytest(str(p) + "::test_hello", "-h")
|
2018-05-23 22:48:46 +08:00
|
|
|
result.stdout.fnmatch_lines(
|
|
|
|
"""
|
2014-07-28 17:48:37 +08:00
|
|
|
*--hello-world*
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
2015-02-27 04:56:44 +08:00
|
|
|
|
|
|
|
|
2019-06-03 06:32:00 +08:00
|
|
|
class TestConftestVisibility:
|
2015-02-27 16:51:53 +08:00
|
|
|
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")
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
package.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
2018-05-23 22:48:46 +08:00
|
|
|
"""\
|
2018-08-24 00:06:17 +08:00
|
|
|
import pytest
|
|
|
|
@pytest.fixture
|
|
|
|
def fxtr():
|
|
|
|
return "from-package"
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
|
|
|
package.join("test_pkgroot.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
2018-05-23 22:48:46 +08:00
|
|
|
"""\
|
2018-08-24 00:06:17 +08:00
|
|
|
def test_pkgroot(fxtr):
|
|
|
|
assert fxtr == "from-package"
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
2015-02-27 16:51:53 +08:00
|
|
|
|
|
|
|
swc = package.mkdir("swc")
|
|
|
|
swc.join("__init__.py").ensure()
|
2018-05-23 22:48:46 +08:00
|
|
|
swc.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
2018-05-23 22:48:46 +08:00
|
|
|
"""\
|
2018-08-24 00:06:17 +08:00
|
|
|
import pytest
|
|
|
|
@pytest.fixture
|
|
|
|
def fxtr():
|
|
|
|
return "from-swc"
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
|
|
|
swc.join("test_with_conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
2018-05-23 22:48:46 +08:00
|
|
|
"""\
|
2018-08-24 00:06:17 +08:00
|
|
|
def test_with_conftest(fxtr):
|
|
|
|
assert fxtr == "from-swc"
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
2015-02-27 16:51:53 +08:00
|
|
|
|
|
|
|
snc = package.mkdir("snc")
|
|
|
|
snc.join("__init__.py").ensure()
|
2018-05-23 22:48:46 +08:00
|
|
|
snc.join("test_no_conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
2018-05-23 22:48:46 +08:00
|
|
|
"""\
|
2018-08-24 00:06:17 +08:00
|
|
|
def test_no_conftest(fxtr):
|
|
|
|
assert fxtr == "from-package" # No local conftest.py, so should
|
|
|
|
# use value from parent dir's
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
)
|
2017-07-21 06:14:54 +08:00
|
|
|
print("created directory structure:")
|
2015-02-27 16:51:53 +08:00
|
|
|
for x in testdir.tmpdir.visit():
|
2017-07-21 06:14:54 +08:00
|
|
|
print(" " + x.relto(testdir.tmpdir))
|
2015-02-27 16:51:53 +08:00
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
return {"runner": runner, "package": package, "swc": swc, "snc": snc}
|
2015-02-27 16:51:53 +08:00
|
|
|
|
|
|
|
# N.B.: "swc" stands for "subdir with conftest.py"
|
|
|
|
# "snc" stands for "subdir no [i.e. without] conftest.py"
|
2018-05-23 22:48:46 +08:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"chdir,testarg,expect_ntests_passed",
|
|
|
|
[
|
|
|
|
# Effective target: package/..
|
|
|
|
("runner", "..", 3),
|
|
|
|
("package", "..", 3),
|
|
|
|
("swc", "../..", 3),
|
|
|
|
("snc", "../..", 3),
|
|
|
|
# Effective target: package
|
|
|
|
("runner", "../package", 3),
|
|
|
|
("package", ".", 3),
|
|
|
|
("swc", "..", 3),
|
|
|
|
("snc", "..", 3),
|
|
|
|
# Effective target: package/swc
|
|
|
|
("runner", "../package/swc", 1),
|
|
|
|
("package", "./swc", 1),
|
|
|
|
("swc", ".", 1),
|
|
|
|
("snc", "../swc", 1),
|
|
|
|
# Effective target: package/snc
|
|
|
|
("runner", "../package/snc", 1),
|
|
|
|
("package", "./snc", 1),
|
|
|
|
("swc", "../snc", 1),
|
|
|
|
("snc", ".", 1),
|
|
|
|
],
|
|
|
|
)
|
2015-02-27 16:51:53 +08:00
|
|
|
def test_parsefactories_relative_node_ids(
|
2018-05-23 22:48:46 +08:00
|
|
|
self, testdir, chdir, testarg, expect_ntests_passed
|
|
|
|
):
|
2019-04-27 22:25:37 +08:00
|
|
|
"""#616"""
|
2015-02-27 16:51:53 +08:00
|
|
|
dirs = self._setup_tree(testdir)
|
2018-05-23 22:48:46 +08:00
|
|
|
print("pytest run in cwd: %s" % (dirs[chdir].relto(testdir.tmpdir)))
|
2017-07-17 07:25:08 +08:00
|
|
|
print("pytestarg : %s" % (testarg))
|
|
|
|
print("expected pass : %s" % (expect_ntests_passed))
|
2015-02-27 16:51:53 +08:00
|
|
|
with dirs[chdir].as_cwd():
|
|
|
|
reprec = testdir.inline_run(testarg, "-q", "--traceconfig")
|
|
|
|
reprec.assertoutcome(passed=expect_ntests_passed)
|
2015-07-24 08:48:59 +08:00
|
|
|
|
|
|
|
|
2018-05-23 22:48:46 +08:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"confcutdir,passed,error", [(".", 2, 0), ("src", 1, 1), (None, 1, 1)]
|
|
|
|
)
|
2015-07-24 08:48:59 +08:00
|
|
|
def test_search_conftest_up_to_inifile(testdir, confcutdir, passed, error):
|
2018-05-13 18:06:09 +08:00
|
|
|
"""Test that conftest files are detected only up to an ini file, unless
|
2015-07-24 08:48:59 +08:00
|
|
|
an explicit --confcutdir option is given.
|
|
|
|
"""
|
|
|
|
root = testdir.tmpdir
|
2018-05-23 22:48:46 +08:00
|
|
|
src = root.join("src").ensure(dir=1)
|
|
|
|
src.join("pytest.ini").write("[pytest]")
|
|
|
|
src.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
import pytest
|
|
|
|
@pytest.fixture
|
|
|
|
def fix1(): pass
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
src.join("test_foo.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def test_1(fix1):
|
|
|
|
pass
|
|
|
|
def test_2(out_of_reach):
|
|
|
|
pass
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
|
|
|
root.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
import pytest
|
|
|
|
@pytest.fixture
|
|
|
|
def out_of_reach(): pass
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2015-07-24 08:48:59 +08:00
|
|
|
|
|
|
|
args = [str(src)]
|
|
|
|
if confcutdir:
|
2018-05-23 22:48:46 +08:00
|
|
|
args = ["--confcutdir=%s" % root.join(confcutdir)]
|
2015-07-24 08:48:59 +08:00
|
|
|
result = testdir.runpytest(*args)
|
2018-05-23 22:48:46 +08:00
|
|
|
match = ""
|
2015-07-24 08:48:59 +08:00
|
|
|
if passed:
|
2018-05-23 22:48:46 +08:00
|
|
|
match += "*%d passed*" % passed
|
2015-07-24 08:48:59 +08:00
|
|
|
if error:
|
2018-05-23 22:48:46 +08:00
|
|
|
match += "*%d error*" % error
|
2015-07-24 08:48:59 +08:00
|
|
|
result.stdout.fnmatch_lines(match)
|
2015-09-28 19:34:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
def test_issue1073_conftest_special_objects(testdir):
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makeconftest(
|
2018-08-24 00:06:17 +08:00
|
|
|
"""\
|
2017-02-17 02:41:51 +08:00
|
|
|
class DontTouchMe(object):
|
2015-09-28 19:34:28 +08:00
|
|
|
def __getattr__(self, x):
|
|
|
|
raise Exception('cant touch me')
|
|
|
|
|
|
|
|
x = DontTouchMe()
|
2018-08-24 00:06:17 +08:00
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
testdir.makepyfile(
|
2018-08-24 00:06:17 +08:00
|
|
|
"""\
|
2015-09-28 19:34:28 +08:00
|
|
|
def test_some():
|
|
|
|
pass
|
2018-08-24 00:06:17 +08:00
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
2015-09-28 19:34:28 +08:00
|
|
|
res = testdir.runpytest()
|
|
|
|
assert res.ret == 0
|
2016-07-05 17:39:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
def test_conftest_exception_handling(testdir):
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makeconftest(
|
2018-08-24 00:06:17 +08:00
|
|
|
"""\
|
2016-07-05 17:39:12 +08:00
|
|
|
raise ValueError()
|
2018-08-24 00:06:17 +08:00
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
|
|
|
testdir.makepyfile(
|
2018-08-24 00:06:17 +08:00
|
|
|
"""\
|
2016-07-05 17:39:12 +08:00
|
|
|
def test_some():
|
|
|
|
pass
|
2018-08-24 00:06:17 +08:00
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
)
|
2016-07-05 17:39:12 +08:00
|
|
|
res = testdir.runpytest()
|
|
|
|
assert res.ret == 4
|
2018-05-23 22:48:46 +08:00
|
|
|
assert "raise ValueError()" in [line.strip() for line in res.errlines]
|
2016-11-21 22:50:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
def test_hook_proxy(testdir):
|
|
|
|
"""Session's gethookproxy() would cache conftests incorrectly (#2016).
|
|
|
|
It was decided to remove the cache altogether.
|
|
|
|
"""
|
2018-05-23 22:48:46 +08:00
|
|
|
testdir.makepyfile(
|
|
|
|
**{
|
|
|
|
"root/demo-0/test_foo1.py": "def test1(): pass",
|
|
|
|
"root/demo-a/test_foo2.py": "def test1(): pass",
|
2018-08-24 00:06:17 +08:00
|
|
|
"root/demo-a/conftest.py": """\
|
2016-11-21 22:50:21 +08:00
|
|
|
def pytest_ignore_collect(path, config):
|
|
|
|
return True
|
|
|
|
""",
|
2018-05-23 22:48:46 +08:00
|
|
|
"root/demo-b/test_foo3.py": "def test1(): pass",
|
|
|
|
"root/demo-c/test_foo4.py": "def test1(): pass",
|
|
|
|
}
|
|
|
|
)
|
2016-11-21 22:50:21 +08:00
|
|
|
result = testdir.runpytest()
|
2018-05-23 22:48:46 +08:00
|
|
|
result.stdout.fnmatch_lines(
|
|
|
|
["*test_foo1.py*", "*test_foo3.py*", "*test_foo4.py*", "*3 passed*"]
|
|
|
|
)
|
2017-06-01 04:55:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
def test_required_option_help(testdir):
|
|
|
|
testdir.makeconftest("assert 0")
|
|
|
|
x = testdir.mkdir("x")
|
2018-05-23 22:48:46 +08:00
|
|
|
x.join("conftest.py").write(
|
2018-08-24 00:06:17 +08:00
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--xyz", action="store_true", required=True)
|
2018-05-23 22:48:46 +08:00
|
|
|
"""
|
|
|
|
)
|
|
|
|
)
|
2017-06-01 04:55:30 +08:00
|
|
|
result = testdir.runpytest("-h", x)
|
2019-10-06 01:18:51 +08:00
|
|
|
result.stdout.no_fnmatch_line("*argument --xyz is required*")
|
2018-05-23 22:48:46 +08:00
|
|
|
assert "general:" in result.stdout.str()
|