summaryrefslogtreecommitdiffstats
path: root/third_party/python/pytest/testing/test_conftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/python/pytest/testing/test_conftest.py')
-rw-r--r--third_party/python/pytest/testing/test_conftest.py543
1 files changed, 543 insertions, 0 deletions
diff --git a/third_party/python/pytest/testing/test_conftest.py b/third_party/python/pytest/testing/test_conftest.py
new file mode 100644
index 0000000000..61b640976f
--- /dev/null
+++ b/third_party/python/pytest/testing/test_conftest.py
@@ -0,0 +1,543 @@
+from __future__ import absolute_import, division, print_function
+from textwrap import dedent
+
+import _pytest._code
+import py
+import pytest
+from _pytest.config import PytestPluginManager
+from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_USAGEERROR
+
+
+@pytest.fixture(scope="module", params=["global", "inpackage"])
+def basedir(request, tmpdir_factory):
+ from _pytest.tmpdir import tmpdir
+
+ tmpdir = tmpdir(request, tmpdir_factory)
+ 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")
+ return tmpdir
+
+
+def ConftestWithSetinitial(path):
+ conftest = PytestPluginManager()
+ conftest_setinitial(conftest, [path])
+ return conftest
+
+
+def conftest_setinitial(conftest, args, confcutdir=None):
+
+ class Namespace(object):
+
+ def __init__(self):
+ self.file_or_dir = args
+ self.confcutdir = str(confcutdir)
+ self.noconftest = False
+
+ conftest._set_initial_conftests(Namespace())
+
+
+class TestConftestValueAccessGlobal(object):
+
+ def test_basic_init(self, basedir):
+ conftest = PytestPluginManager()
+ p = basedir.join("adir")
+ assert conftest._rget_with_confmod("a", p)[1] == 1
+
+ def test_immediate_initialiation_and_incremental_are_the_same(self, basedir):
+ conftest = PytestPluginManager()
+ len(conftest._path2confmods)
+ conftest._getconftestmodules(basedir)
+ snap1 = len(conftest._path2confmods)
+ # assert len(conftest._path2confmods) == snap1 + 1
+ conftest._getconftestmodules(basedir.join("adir"))
+ assert len(conftest._path2confmods) == snap1 + 1
+ conftest._getconftestmodules(basedir.join("b"))
+ assert len(conftest._path2confmods) == snap1 + 2
+
+ def test_value_access_not_existing(self, basedir):
+ conftest = ConftestWithSetinitial(basedir)
+ with pytest.raises(KeyError):
+ conftest._rget_with_confmod("a", basedir)
+
+ def test_value_access_by_path(self, basedir):
+ conftest = ConftestWithSetinitial(basedir)
+ adir = basedir.join("adir")
+ assert conftest._rget_with_confmod("a", adir)[1] == 1
+ assert conftest._rget_with_confmod("a", adir.join("b"))[1] == 1.5
+
+ def test_value_access_with_confmod(self, basedir):
+ startdir = basedir.join("adir", "b")
+ startdir.ensure("xx", dir=True)
+ conftest = ConftestWithSetinitial(startdir)
+ mod, value = conftest._rget_with_confmod("a", startdir)
+ assert value == 1.5
+ path = py.path.local(mod.__file__)
+ assert path.dirpath() == basedir.join("adir", "b")
+ assert path.purebasename.startswith("conftest")
+
+
+def test_conftest_in_nonpkg_with_init(tmpdir):
+ 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")
+ ConftestWithSetinitial(tmpdir.join("adir-1.0", "b"))
+
+
+def test_doubledash_considered(testdir):
+ conf = testdir.mkdir("--option")
+ conf.ensure("conftest.py")
+ conftest = PytestPluginManager()
+ conftest_setinitial(conftest, [conf.basename, conf.basename])
+ values = conftest._getconftestmodules(conf)
+ assert len(values) == 1
+
+
+def test_issue151_load_all_conftests(testdir):
+ names = "code proj src".split()
+ for name in names:
+ p = testdir.mkdir(name)
+ p.ensure("conftest.py")
+
+ conftest = PytestPluginManager()
+ conftest_setinitial(conftest, names)
+ d = list(conftest._conftestpath2mod.values())
+ assert len(d) == len(names)
+
+
+def test_conftest_global_import(testdir):
+ testdir.makeconftest("x=3")
+ p = testdir.makepyfile(
+ """
+ import py, pytest
+ from _pytest.config import PytestPluginManager
+ conf = PytestPluginManager()
+ mod = conf._importconftest(py.path.local("conftest.py"))
+ assert mod.x == 3
+ import conftest
+ assert conftest is mod, (conftest, mod)
+ subconf = py.path.local().ensure("sub", "conftest.py")
+ subconf.write("y=4")
+ mod2 = conf._importconftest(subconf)
+ assert mod != mod2
+ assert mod2.y == 4
+ import conftest
+ assert conftest is mod2, (conftest, mod)
+ """
+ )
+ res = testdir.runpython(p)
+ assert res.ret == 0
+
+
+def test_conftestcutdir(testdir):
+ conf = testdir.makeconftest("")
+ p = testdir.mkdir("x")
+ conftest = PytestPluginManager()
+ conftest_setinitial(conftest, [testdir.tmpdir], confcutdir=p)
+ values = conftest._getconftestmodules(p)
+ assert len(values) == 0
+ values = conftest._getconftestmodules(conf.dirpath())
+ assert len(values) == 0
+ assert conf not in conftest._conftestpath2mod
+ # but we can still import a conftest directly
+ conftest._importconftest(conf)
+ values = conftest._getconftestmodules(conf.dirpath())
+ assert values[0].__file__.startswith(str(conf))
+ # and all sub paths get updated properly
+ values = conftest._getconftestmodules(p)
+ assert len(values) == 1
+ assert values[0].__file__.startswith(str(conf))
+
+
+def test_conftestcutdir_inplace_considered(testdir):
+ conf = testdir.makeconftest("")
+ conftest = PytestPluginManager()
+ conftest_setinitial(conftest, [conf.dirpath()], confcutdir=conf.dirpath())
+ values = conftest._getconftestmodules(conf.dirpath())
+ assert len(values) == 1
+ assert values[0].__file__.startswith(str(conf))
+
+
+@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 = PytestPluginManager()
+ conftest_setinitial(conftest, [sub.dirpath()], confcutdir=testdir.tmpdir)
+ if name not in ("whatever", ".dotdir"):
+ assert subconftest in conftest._conftestpath2mod
+ assert len(conftest._conftestpath2mod) == 1
+ else:
+ assert subconftest not in conftest._conftestpath2mod
+ assert len(conftest._conftestpath2mod) == 0
+
+
+def test_conftest_confcutdir(testdir):
+ testdir.makeconftest("assert 0")
+ x = testdir.mkdir("x")
+ x.join("conftest.py").write(
+ _pytest._code.Source(
+ """
+ def pytest_addoption(parser):
+ parser.addoption("--xyz", action="store_true")
+ """
+ )
+ )
+ result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
+ result.stdout.fnmatch_lines(["*--xyz*"])
+ assert "warning: could not load initial" not in result.stdout.str()
+
+
+def test_no_conftest(testdir):
+ testdir.makeconftest("assert 0")
+ result = testdir.runpytest("--noconftest")
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+
+ result = testdir.runpytest()
+ assert result.ret == EXIT_USAGEERROR
+
+
+def test_conftest_existing_resultlog(testdir):
+ x = testdir.mkdir("tests")
+ x.join("conftest.py").write(
+ _pytest._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(
+ _pytest._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")
+ ct2 = sub.join("conftest.py")
+ ct2.write("")
+
+ def impct(p):
+ return p
+
+ conftest = PytestPluginManager()
+ conftest._confcutdir = testdir.tmpdir
+ monkeypatch.setattr(conftest, "_importconftest", impct)
+ assert conftest._getconftestmodules(sub) == [ct1, ct2]
+
+
+def test_fixture_dependency(testdir, monkeypatch):
+ ct1 = testdir.makeconftest("")
+ ct1 = testdir.makepyfile("__init__.py")
+ ct1.write("")
+ sub = testdir.mkdir("sub")
+ sub.join("__init__.py").write("")
+ sub.join("conftest.py").write(
+ dedent(
+ """
+ import pytest
+
+ @pytest.fixture
+ def not_needed():
+ assert False, "Should not be called!"
+
+ @pytest.fixture
+ def foo():
+ assert False, "Should not be called!"
+
+ @pytest.fixture
+ def bar(foo):
+ return 'bar'
+ """
+ )
+ )
+ subsub = sub.mkdir("subsub")
+ subsub.join("__init__.py").write("")
+ subsub.join("test_bar.py").write(
+ dedent(
+ """
+ import pytest
+
+ @pytest.fixture
+ def bar():
+ return 'sub bar'
+
+ def test_event_fixture(bar):
+ assert bar == 'sub bar'
+ """
+ )
+ )
+ result = testdir.runpytest("sub")
+ result.stdout.fnmatch_lines(["*1 passed*"])
+
+
+def test_conftest_found_with_double_dash(testdir):
+ sub = testdir.mkdir("sub")
+ sub.join("conftest.py").write(
+ dedent(
+ """
+ def pytest_addoption(parser):
+ parser.addoption("--hello-world", action="store_true")
+ """
+ )
+ )
+ p = sub.join("test_hello.py")
+ p.write("def test_hello(): pass")
+ result = testdir.runpytest(str(p) + "::test_hello", "-h")
+ result.stdout.fnmatch_lines(
+ """
+ *--hello-world*
+ """
+ )
+
+
+class TestConftestVisibility(object):
+
+ 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",
+ [
+ # 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),
+ ],
+ )
+ @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)
+
+
+@pytest.mark.parametrize(
+ "confcutdir,passed,error", [(".", 2, 0), ("src", 1, 1), (None, 1, 1)]
+)
+def test_search_conftest_up_to_inifile(testdir, confcutdir, passed, error):
+ """Test that conftest files are detected only up to an ini file, unless
+ an explicit --confcutdir option is given.
+ """
+ root = testdir.tmpdir
+ src = root.join("src").ensure(dir=1)
+ src.join("pytest.ini").write("[pytest]")
+ src.join("conftest.py").write(
+ _pytest._code.Source(
+ """
+ import pytest
+ @pytest.fixture
+ def fix1(): pass
+ """
+ )
+ )
+ src.join("test_foo.py").write(
+ _pytest._code.Source(
+ """
+ def test_1(fix1):
+ pass
+ def test_2(out_of_reach):
+ pass
+ """
+ )
+ )
+ root.join("conftest.py").write(
+ _pytest._code.Source(
+ """
+ import pytest
+ @pytest.fixture
+ def out_of_reach(): pass
+ """
+ )
+ )
+
+ args = [str(src)]
+ if confcutdir:
+ args = ["--confcutdir=%s" % root.join(confcutdir)]
+ result = testdir.runpytest(*args)
+ match = ""
+ if passed:
+ match += "*%d passed*" % passed
+ if error:
+ match += "*%d error*" % error
+ result.stdout.fnmatch_lines(match)
+
+
+def test_issue1073_conftest_special_objects(testdir):
+ testdir.makeconftest(
+ """
+ class DontTouchMe(object):
+ def __getattr__(self, x):
+ raise Exception('cant touch me')
+
+ x = DontTouchMe()
+ """
+ )
+ testdir.makepyfile(
+ """
+ def test_some():
+ pass
+ """
+ )
+ res = testdir.runpytest()
+ assert res.ret == 0
+
+
+def test_conftest_exception_handling(testdir):
+ testdir.makeconftest(
+ """
+ raise ValueError()
+ """
+ )
+ testdir.makepyfile(
+ """
+ def test_some():
+ pass
+ """
+ )
+ res = testdir.runpytest()
+ assert res.ret == 4
+ assert "raise ValueError()" in [line.strip() for line in res.errlines]
+
+
+def test_hook_proxy(testdir):
+ """Session's gethookproxy() would cache conftests incorrectly (#2016).
+ It was decided to remove the cache altogether.
+ """
+ testdir.makepyfile(
+ **{
+ "root/demo-0/test_foo1.py": "def test1(): pass",
+ "root/demo-a/test_foo2.py": "def test1(): pass",
+ "root/demo-a/conftest.py": """
+ def pytest_ignore_collect(path, config):
+ return True
+ """,
+ "root/demo-b/test_foo3.py": "def test1(): pass",
+ "root/demo-c/test_foo4.py": "def test1(): pass",
+ }
+ )
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines(
+ ["*test_foo1.py*", "*test_foo3.py*", "*test_foo4.py*", "*3 passed*"]
+ )
+
+
+def test_required_option_help(testdir):
+ testdir.makeconftest("assert 0")
+ x = testdir.mkdir("x")
+ x.join("conftest.py").write(
+ _pytest._code.Source(
+ """
+ def pytest_addoption(parser):
+ parser.addoption("--xyz", action="store_true", required=True)
+ """
+ )
+ )
+ result = testdir.runpytest("-h", x)
+ assert "argument --xyz is required" not in result.stdout.str()
+ assert "general:" in result.stdout.str()