diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 6833eb021..0d1f8f278 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1190,7 +1190,9 @@ class Pytester: config._do_configure() return config - def getitem(self, source: str, funcname: str = "test_func") -> Item: + def getitem( + self, source: Union[str, "os.PathLike[str]"], funcname: str = "test_func" + ) -> Item: """Return the test item for a test function. Writes the source to a python file and runs pytest's collection on @@ -1210,7 +1212,7 @@ class Pytester: funcname, source, items ) - def getitems(self, source: str) -> List[Item]: + def getitems(self, source: Union[str, "os.PathLike[str]"]) -> List[Item]: """Return all test items collected from the module. Writes the source to a Python file and runs pytest's collection on @@ -1220,7 +1222,11 @@ class Pytester: return self.genitems([modcol]) def getmodulecol( - self, source: Union[str, Path], configargs=(), *, withinit: bool = False + self, + source: Union[str, "os.PathLike[str]"], + configargs=(), + *, + withinit: bool = False, ): """Return the module collection node for ``source``. @@ -1238,7 +1244,9 @@ class Pytester: Whether to also write an ``__init__.py`` file to the same directory to ensure it is a package. """ - if isinstance(source, Path): + # TODO: Remove type ignore in next mypy release (> 0.790). + # https://github.com/python/typeshed/pull/4582 + if isinstance(source, os.PathLike): # type: ignore[misc] path = self.path.joinpath(source) assert not withinit, "not supported for paths" else: diff --git a/testing/python/collect.py b/testing/python/collect.py index 4d5f4c689..c52fb017d 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1,3 +1,4 @@ +import os import sys import textwrap from typing import Any @@ -6,42 +7,50 @@ from typing import Dict import _pytest._code import pytest from _pytest.config import ExitCode +from _pytest.monkeypatch import MonkeyPatch from _pytest.nodes import Collector -from _pytest.pytester import Testdir +from _pytest.pytester import Pytester +from _pytest.python import Class +from _pytest.python import Instance class TestModule: - def test_failing_import(self, testdir): - modcol = testdir.getmodulecol("import alksdjalskdjalkjals") + def test_failing_import(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol("import alksdjalskdjalkjals") pytest.raises(Collector.CollectError, modcol.collect) - def test_import_duplicate(self, testdir): - a = testdir.mkdir("a") - b = testdir.mkdir("b") - p = a.ensure("test_whatever.py") - p.pyimport() - del sys.modules["test_whatever"] - b.ensure("test_whatever.py") - result = testdir.runpytest() + def test_import_duplicate(self, pytester: Pytester) -> None: + a = pytester.mkdir("a") + b = pytester.mkdir("b") + p1 = a.joinpath("test_whatever.py") + p1.touch() + p2 = b.joinpath("test_whatever.py") + p2.touch() + # ensure we don't have it imported already + sys.modules.pop(p1.stem, None) + + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*import*mismatch*", "*imported*test_whatever*", - "*%s*" % a.join("test_whatever.py"), + "*%s*" % p1, "*not the same*", - "*%s*" % b.join("test_whatever.py"), + "*%s*" % p2, "*HINT*", ] ) - def test_import_prepend_append(self, testdir, monkeypatch): - root1 = testdir.mkdir("root1") - root2 = testdir.mkdir("root2") - root1.ensure("x456.py") - root2.ensure("x456.py") - p = root2.join("test_x456.py") + def test_import_prepend_append( + self, pytester: Pytester, monkeypatch: MonkeyPatch + ) -> None: + root1 = pytester.mkdir("root1") + root2 = pytester.mkdir("root2") + root1.joinpath("x456.py").touch() + root2.joinpath("x456.py").touch() + p = root2.joinpath("test_x456.py") monkeypatch.syspath_prepend(str(root1)) - p.write( + p.write_text( textwrap.dedent( """\ import x456 @@ -52,25 +61,26 @@ class TestModule: ) ) ) - with root2.as_cwd(): - reprec = testdir.inline_run("--import-mode=append") + with monkeypatch.context() as mp: + mp.chdir(root2) + reprec = pytester.inline_run("--import-mode=append") reprec.assertoutcome(passed=0, failed=1) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_syntax_error_in_module(self, testdir): - modcol = testdir.getmodulecol("this is a syntax error") + def test_syntax_error_in_module(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol("this is a syntax error") pytest.raises(modcol.CollectError, modcol.collect) pytest.raises(modcol.CollectError, modcol.collect) - def test_module_considers_pluginmanager_at_import(self, testdir): - modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',") + def test_module_considers_pluginmanager_at_import(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol("pytest_plugins='xasdlkj',") pytest.raises(ImportError, lambda: modcol.obj) - def test_invalid_test_module_name(self, testdir): - a = testdir.mkdir("a") - a.ensure("test_one.part1.py") - result = testdir.runpytest() + def test_invalid_test_module_name(self, pytester: Pytester) -> None: + a = pytester.mkdir("a") + a.joinpath("test_one.part1.py").touch() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "ImportError while importing test module*test_one.part1*", @@ -79,24 +89,26 @@ class TestModule: ) @pytest.mark.parametrize("verbose", [0, 1, 2]) - def test_show_traceback_import_error(self, testdir, verbose): + def test_show_traceback_import_error( + self, pytester: Pytester, verbose: int + ) -> None: """Import errors when collecting modules should display the traceback (#1976). With low verbosity we omit pytest and internal modules, otherwise show all traceback entries. """ - testdir.makepyfile( + pytester.makepyfile( foo_traceback_import_error=""" from bar_traceback_import_error import NOT_AVAILABLE """, bar_traceback_import_error="", ) - testdir.makepyfile( + pytester.makepyfile( """ import foo_traceback_import_error """ ) args = ("-v",) * verbose - result = testdir.runpytest(*args) + result = pytester.runpytest(*args) result.stdout.fnmatch_lines( [ "ImportError while importing test module*", @@ -113,12 +125,12 @@ class TestModule: else: assert "_pytest" not in stdout - def test_show_traceback_import_error_unicode(self, testdir): + def test_show_traceback_import_error_unicode(self, pytester: Pytester) -> None: """Check test modules collected which raise ImportError with unicode messages are handled properly (#2336). """ - testdir.makepyfile("raise ImportError('Something bad happened ☺')") - result = testdir.runpytest() + pytester.makepyfile("raise ImportError('Something bad happened ☺')") + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "ImportError while importing test module*", @@ -130,15 +142,15 @@ class TestModule: class TestClass: - def test_class_with_init_warning(self, testdir): - testdir.makepyfile( + def test_class_with_init_warning(self, pytester: Pytester) -> None: + pytester.makepyfile( """ class TestClass1(object): def __init__(self): pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*cannot collect test class 'TestClass1' because it has " @@ -146,15 +158,15 @@ class TestClass: ] ) - def test_class_with_new_warning(self, testdir): - testdir.makepyfile( + def test_class_with_new_warning(self, pytester: Pytester) -> None: + pytester.makepyfile( """ class TestClass1(object): def __new__(self): pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*cannot collect test class 'TestClass1' because it has " @@ -162,19 +174,19 @@ class TestClass: ] ) - def test_class_subclassobject(self, testdir): - testdir.getmodulecol( + def test_class_subclassobject(self, pytester: Pytester) -> None: + pytester.getmodulecol( """ class test(object): pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*collected 0*"]) - def test_static_method(self, testdir): + def test_static_method(self, pytester: Pytester) -> None: """Support for collecting staticmethod tests (#2528, #2699)""" - testdir.getmodulecol( + pytester.getmodulecol( """ import pytest class Test(object): @@ -191,11 +203,11 @@ class TestClass: assert fix == 1 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*collected 2 items*", "*2 passed in*"]) - def test_setup_teardown_class_as_classmethod(self, testdir): - testdir.makepyfile( + def test_setup_teardown_class_as_classmethod(self, pytester: Pytester) -> None: + pytester.makepyfile( test_mod1=""" class TestClassMethod(object): @classmethod @@ -208,11 +220,11 @@ class TestClass: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - def test_issue1035_obj_has_getattr(self, testdir): - modcol = testdir.getmodulecol( + def test_issue1035_obj_has_getattr(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ class Chameleon(object): def __getattr__(self, name): @@ -223,22 +235,22 @@ class TestClass: colitems = modcol.collect() assert len(colitems) == 0 - def test_issue1579_namedtuple(self, testdir): - testdir.makepyfile( + def test_issue1579_namedtuple(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import collections TestCase = collections.namedtuple('TestCase', ['a']) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( "*cannot collect test class 'TestCase' " "because it has a __new__ constructor*" ) - def test_issue2234_property(self, testdir): - testdir.makepyfile( + def test_issue2234_property(self, pytester: Pytester) -> None: + pytester.makepyfile( """ class TestCase(object): @property @@ -246,20 +258,20 @@ class TestClass: raise NotImplementedError() """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == ExitCode.NO_TESTS_COLLECTED class TestFunction: - def test_getmodulecollector(self, testdir): - item = testdir.getitem("def test_func(): pass") + def test_getmodulecollector(self, pytester: Pytester) -> None: + item = pytester.getitem("def test_func(): pass") modcol = item.getparent(pytest.Module) assert isinstance(modcol, pytest.Module) assert hasattr(modcol.obj, "test_func") @pytest.mark.filterwarnings("default") - def test_function_as_object_instance_ignored(self, testdir): - testdir.makepyfile( + def test_function_as_object_instance_ignored(self, pytester: Pytester) -> None: + pytester.makepyfile( """ class A(object): def __call__(self, tmpdir): @@ -268,7 +280,7 @@ class TestFunction: test_a = A() """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "collected 0 items", @@ -278,37 +290,37 @@ class TestFunction: ) @staticmethod - def make_function(testdir, **kwargs): + def make_function(pytester: Pytester, **kwargs: Any) -> Any: from _pytest.fixtures import FixtureManager - config = testdir.parseconfigure() - session = testdir.Session.from_config(config) + config = pytester.parseconfigure() + session = pytester.Session.from_config(config) session._fixturemanager = FixtureManager(session) return pytest.Function.from_parent(parent=session, **kwargs) - def test_function_equality(self, testdir): + def test_function_equality(self, pytester: Pytester) -> None: def func1(): pass def func2(): pass - f1 = self.make_function(testdir, name="name", callobj=func1) + f1 = self.make_function(pytester, name="name", callobj=func1) assert f1 == f1 f2 = self.make_function( - testdir, name="name", callobj=func2, originalname="foobar" + pytester, name="name", callobj=func2, originalname="foobar" ) assert f1 != f2 - def test_repr_produces_actual_test_id(self, testdir): + def test_repr_produces_actual_test_id(self, pytester: Pytester) -> None: f = self.make_function( - testdir, name=r"test[\xe5]", callobj=self.test_repr_produces_actual_test_id + pytester, name=r"test[\xe5]", callobj=self.test_repr_produces_actual_test_id ) assert repr(f) == r"" - def test_issue197_parametrize_emptyset(self, testdir): - testdir.makepyfile( + def test_issue197_parametrize_emptyset(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.mark.parametrize('arg', []) @@ -316,11 +328,11 @@ class TestFunction: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(skipped=1) - def test_single_tuple_unwraps_values(self, testdir): - testdir.makepyfile( + def test_single_tuple_unwraps_values(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.mark.parametrize(('arg',), [(1,)]) @@ -328,11 +340,11 @@ class TestFunction: assert arg == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_issue213_parametrize_value_no_equal(self, testdir): - testdir.makepyfile( + def test_issue213_parametrize_value_no_equal(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest class A(object): @@ -343,12 +355,12 @@ class TestFunction: assert arg.__class__.__name__ == "A" """ ) - reprec = testdir.inline_run("--fulltrace") + reprec = pytester.inline_run("--fulltrace") reprec.assertoutcome(passed=1) - def test_parametrize_with_non_hashable_values(self, testdir): + def test_parametrize_with_non_hashable_values(self, pytester: Pytester) -> None: """Test parametrization with non-hashable values.""" - testdir.makepyfile( + pytester.makepyfile( """ archival_mapping = { '1.0': {'tag': '1.0'}, @@ -363,12 +375,14 @@ class TestFunction: assert value == archival_mapping[key] """ ) - rec = testdir.inline_run() + rec = pytester.inline_run() rec.assertoutcome(passed=2) - def test_parametrize_with_non_hashable_values_indirect(self, testdir): + def test_parametrize_with_non_hashable_values_indirect( + self, pytester: Pytester + ) -> None: """Test parametrization with non-hashable values with indirect parametrization.""" - testdir.makepyfile( + pytester.makepyfile( """ archival_mapping = { '1.0': {'tag': '1.0'}, @@ -392,12 +406,12 @@ class TestFunction: assert value == archival_mapping[key] """ ) - rec = testdir.inline_run() + rec = pytester.inline_run() rec.assertoutcome(passed=2) - def test_parametrize_overrides_fixture(self, testdir): + def test_parametrize_overrides_fixture(self, pytester: Pytester) -> None: """Test parametrization when parameter overrides existing fixture with same name.""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -421,12 +435,14 @@ class TestFunction: assert value == 'overridden' """ ) - rec = testdir.inline_run() + rec = pytester.inline_run() rec.assertoutcome(passed=3) - def test_parametrize_overrides_parametrized_fixture(self, testdir): + def test_parametrize_overrides_parametrized_fixture( + self, pytester: Pytester + ) -> None: """Test parametrization when parameter overrides existing parametrized fixture with same name.""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -440,12 +456,14 @@ class TestFunction: assert value == 'overridden' """ ) - rec = testdir.inline_run() + rec = pytester.inline_run() rec.assertoutcome(passed=1) - def test_parametrize_overrides_indirect_dependency_fixture(self, testdir): + def test_parametrize_overrides_indirect_dependency_fixture( + self, pytester: Pytester + ) -> None: """Test parametrization when parameter overrides a fixture that a test indirectly depends on""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -471,11 +489,11 @@ class TestFunction: assert not fix3_instantiated """ ) - rec = testdir.inline_run() + rec = pytester.inline_run() rec.assertoutcome(passed=1) - def test_parametrize_with_mark(self, testdir): - items = testdir.getitems( + def test_parametrize_with_mark(self, pytester: Pytester) -> None: + items = pytester.getitems( """ import pytest @pytest.mark.foo @@ -495,8 +513,8 @@ class TestFunction: ) assert "foo" in keywords[1] and "bar" in keywords[1] and "baz" in keywords[1] - def test_parametrize_with_empty_string_arguments(self, testdir): - items = testdir.getitems( + def test_parametrize_with_empty_string_arguments(self, pytester: Pytester) -> None: + items = pytester.getitems( """\ import pytest @@ -508,8 +526,8 @@ class TestFunction: names = {item.name for item in items} assert names == {"test[-]", "test[ -]", "test[- ]", "test[ - ]"} - def test_function_equality_with_callspec(self, testdir): - items = testdir.getitems( + def test_function_equality_with_callspec(self, pytester: Pytester) -> None: + items = pytester.getitems( """ import pytest @pytest.mark.parametrize('arg', [1,2]) @@ -520,8 +538,8 @@ class TestFunction: assert items[0] != items[1] assert not (items[0] == items[1]) - def test_pyfunc_call(self, testdir): - item = testdir.getitem("def test_func(): raise ValueError") + def test_pyfunc_call(self, pytester: Pytester) -> None: + item = pytester.getitem("def test_func(): raise ValueError") config = item.config class MyPlugin1: @@ -537,8 +555,8 @@ class TestFunction: config.hook.pytest_runtest_setup(item=item) config.hook.pytest_pyfunc_call(pyfuncitem=item) - def test_multiple_parametrize(self, testdir): - modcol = testdir.getmodulecol( + def test_multiple_parametrize(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ import pytest @pytest.mark.parametrize('x', [0, 1]) @@ -553,8 +571,8 @@ class TestFunction: assert colitems[2].name == "test1[3-0]" assert colitems[3].name == "test1[3-1]" - def test_issue751_multiple_parametrize_with_ids(self, testdir): - modcol = testdir.getmodulecol( + def test_issue751_multiple_parametrize_with_ids(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ import pytest @pytest.mark.parametrize('x', [0], ids=['c']) @@ -572,8 +590,8 @@ class TestFunction: assert colitems[2].name == "test2[a-c]" assert colitems[3].name == "test2[b-c]" - def test_parametrize_skipif(self, testdir): - testdir.makepyfile( + def test_parametrize_skipif(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -584,11 +602,11 @@ class TestFunction: assert x < 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed, 1 skipped in *"]) - def test_parametrize_skip(self, testdir): - testdir.makepyfile( + def test_parametrize_skip(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -599,11 +617,11 @@ class TestFunction: assert x < 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed, 1 skipped in *"]) - def test_parametrize_skipif_no_skip(self, testdir): - testdir.makepyfile( + def test_parametrize_skipif_no_skip(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -614,11 +632,11 @@ class TestFunction: assert x < 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 1 failed, 2 passed in *"]) - def test_parametrize_xfail(self, testdir): - testdir.makepyfile( + def test_parametrize_xfail(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -629,11 +647,11 @@ class TestFunction: assert x < 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed, 1 xfailed in *"]) - def test_parametrize_passed(self, testdir): - testdir.makepyfile( + def test_parametrize_passed(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -644,11 +662,11 @@ class TestFunction: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed, 1 xpassed in *"]) - def test_parametrize_xfail_passed(self, testdir): - testdir.makepyfile( + def test_parametrize_xfail_passed(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -659,11 +677,11 @@ class TestFunction: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 3 passed in *"]) - def test_function_originalname(self, testdir: Testdir) -> None: - items = testdir.getitems( + def test_function_originalname(self, pytester: Pytester) -> None: + items = pytester.getitems( """ import pytest @@ -685,14 +703,14 @@ class TestFunction: "test_no_param", ] - def test_function_with_square_brackets(self, testdir: Testdir) -> None: + def test_function_with_square_brackets(self, pytester: Pytester) -> None: """Check that functions with square brackets don't cause trouble.""" - p1 = testdir.makepyfile( + p1 = pytester.makepyfile( """ locals()["test_foo[name]"] = lambda: None """ ) - result = testdir.runpytest("-v", str(p1)) + result = pytester.runpytest("-v", str(p1)) result.stdout.fnmatch_lines( [ "test_function_with_square_brackets.py::test_foo[[]name[]] PASSED *", @@ -702,23 +720,23 @@ class TestFunction: class TestSorting: - def test_check_equality(self, testdir) -> None: - modcol = testdir.getmodulecol( + def test_check_equality(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ def test_pass(): pass def test_fail(): assert 0 """ ) - fn1 = testdir.collect_by_name(modcol, "test_pass") + fn1 = pytester.collect_by_name(modcol, "test_pass") assert isinstance(fn1, pytest.Function) - fn2 = testdir.collect_by_name(modcol, "test_pass") + fn2 = pytester.collect_by_name(modcol, "test_pass") assert isinstance(fn2, pytest.Function) assert fn1 == fn2 assert fn1 != modcol assert hash(fn1) == hash(fn2) - fn3 = testdir.collect_by_name(modcol, "test_fail") + fn3 = pytester.collect_by_name(modcol, "test_fail") assert isinstance(fn3, pytest.Function) assert not (fn1 == fn3) assert fn1 != fn3 @@ -730,8 +748,8 @@ class TestSorting: assert [1, 2, 3] != fn # type: ignore[comparison-overlap] assert modcol != fn - def test_allow_sane_sorting_for_decorators(self, testdir): - modcol = testdir.getmodulecol( + def test_allow_sane_sorting_for_decorators(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ def dec(f): g = lambda: f(2) @@ -754,8 +772,8 @@ class TestSorting: class TestConftestCustomization: - def test_pytest_pycollect_module(self, testdir): - testdir.makeconftest( + def test_pytest_pycollect_module(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest class MyModule(pytest.Module): @@ -765,14 +783,15 @@ class TestConftestCustomization: return MyModule.from_parent(fspath=path, parent=parent) """ ) - testdir.makepyfile("def test_some(): pass") - testdir.makepyfile(test_xyz="def test_func(): pass") - result = testdir.runpytest("--collect-only") + pytester.makepyfile("def test_some(): pass") + pytester.makepyfile(test_xyz="def test_func(): pass") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["* None: + b = pytester.path.joinpath("a", "b") + b.mkdir(parents=True) + b.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -784,7 +803,7 @@ class TestConftestCustomization: """ ) ) - b.join("test_module.py").write( + b.joinpath("test_module.py").write_text( textwrap.dedent( """\ def test_hello(): @@ -792,12 +811,13 @@ class TestConftestCustomization: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_customized_pymakeitem(self, testdir): - b = testdir.mkdir("a").mkdir("b") - b.join("conftest.py").write( + def test_customized_pymakeitem(self, pytester: Pytester) -> None: + b = pytester.path.joinpath("a", "b") + b.mkdir(parents=True) + b.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -812,7 +832,7 @@ class TestConftestCustomization: """ ) ) - b.join("test_module.py").write( + b.joinpath("test_module.py").write_text( textwrap.dedent( """\ import pytest @@ -825,11 +845,11 @@ class TestConftestCustomization: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_pytest_pycollect_makeitem(self, testdir): - testdir.makeconftest( + def test_pytest_pycollect_makeitem(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest class MyFunction(pytest.Function): @@ -839,16 +859,16 @@ class TestConftestCustomization: return MyFunction.from_parent(name=name, parent=collector) """ ) - testdir.makepyfile("def some(): pass") - result = testdir.runpytest("--collect-only") + pytester.makepyfile("def some(): pass") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*MyFunction*some*"]) - def test_issue2369_collect_module_fileext(self, testdir): + def test_issue2369_collect_module_fileext(self, pytester: Pytester) -> None: """Ensure we can collect files with weird file extensions as Python modules (#2369)""" # We'll implement a little finder and loader to import files containing # Python source code whose file extension is ".narf". - testdir.makeconftest( + pytester.makeconftest( """ import sys, os, imp from _pytest.python import Module @@ -866,17 +886,17 @@ class TestConftestCustomization: if path.ext == ".narf": return Module.from_parent(fspath=path, parent=parent)""" ) - testdir.makefile( + pytester.makefile( ".narf", """\ def test_something(): assert 1 + 1 == 2""", ) # Use runpytest_subprocess, since we're futzing with sys.meta_path. - result = testdir.runpytest_subprocess() + result = pytester.runpytest_subprocess() result.stdout.fnmatch_lines(["*1 passed*"]) - def test_early_ignored_attributes(self, testdir: Testdir) -> None: + def test_early_ignored_attributes(self, pytester: Pytester) -> None: """Builtin attributes should be ignored early on, even if configuration would otherwise allow them. @@ -884,14 +904,14 @@ class TestConftestCustomization: although it tests PytestCollectionWarning is not raised, while it would have been raised otherwise. """ - testdir.makeini( + pytester.makeini( """ [pytest] python_classes=* python_functions=* """ ) - testdir.makepyfile( + pytester.makepyfile( """ class TestEmpty: pass @@ -900,15 +920,15 @@ class TestConftestCustomization: pass """ ) - items, rec = testdir.inline_genitems() + items, rec = pytester.inline_genitems() assert rec.ret == 0 assert len(items) == 1 -def test_setup_only_available_in_subdir(testdir): - sub1 = testdir.mkpydir("sub1") - sub2 = testdir.mkpydir("sub2") - sub1.join("conftest.py").write( +def test_setup_only_available_in_subdir(pytester: Pytester) -> None: + sub1 = pytester.mkpydir("sub1") + sub2 = pytester.mkpydir("sub2") + sub1.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -921,7 +941,7 @@ def test_setup_only_available_in_subdir(testdir): """ ) ) - sub2.join("conftest.py").write( + sub2.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -934,14 +954,14 @@ def test_setup_only_available_in_subdir(testdir): """ ) ) - sub1.join("test_in_sub1.py").write("def test_1(): pass") - sub2.join("test_in_sub2.py").write("def test_2(): pass") - result = testdir.runpytest("-v", "-s") + sub1.joinpath("test_in_sub1.py").write_text("def test_1(): pass") + sub2.joinpath("test_in_sub2.py").write_text("def test_2(): pass") + result = pytester.runpytest("-v", "-s") result.assert_outcomes(passed=2) -def test_modulecol_roundtrip(testdir): - modcol = testdir.getmodulecol("pass", withinit=False) +def test_modulecol_roundtrip(pytester: Pytester) -> None: + modcol = pytester.getmodulecol("pass", withinit=False) trail = modcol.nodeid newcol = modcol.session.perform_collect([trail], genitems=0)[0] assert modcol.name == newcol.name @@ -956,8 +976,8 @@ class TestTracebackCutting: assert excinfo.traceback[-2].frame.code.name == "test_skip_simple" assert not excinfo.traceback[-2].ishidden() - def test_traceback_argsetup(self, testdir): - testdir.makeconftest( + def test_traceback_argsetup(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @@ -966,8 +986,8 @@ class TestTracebackCutting: raise ValueError("xyz") """ ) - p = testdir.makepyfile("def test(hello): pass") - result = testdir.runpytest(p) + p = pytester.makepyfile("def test(hello): pass") + result = pytester.runpytest(p) assert result.ret != 0 out = result.stdout.str() assert "xyz" in out @@ -975,14 +995,14 @@ class TestTracebackCutting: numentries = out.count("_ _ _") # separator for traceback entries assert numentries == 0 - result = testdir.runpytest("--fulltrace", p) + result = pytester.runpytest("--fulltrace", p) out = result.stdout.str() assert "conftest.py:5: ValueError" in out numentries = out.count("_ _ _ _") # separator for traceback entries assert numentries > 3 - def test_traceback_error_during_import(self, testdir): - testdir.makepyfile( + def test_traceback_error_during_import(self, pytester: Pytester) -> None: + pytester.makepyfile( """ x = 1 x = 2 @@ -990,21 +1010,23 @@ class TestTracebackCutting: asd """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret != 0 out = result.stdout.str() assert "x = 1" not in out assert "x = 2" not in out result.stdout.fnmatch_lines([" *asd*", "E*NameError*"]) - result = testdir.runpytest("--fulltrace") + result = pytester.runpytest("--fulltrace") out = result.stdout.str() assert "x = 1" in out assert "x = 2" in out result.stdout.fnmatch_lines([">*asd*", "E*NameError*"]) - def test_traceback_filter_error_during_fixture_collection(self, testdir): + def test_traceback_filter_error_during_fixture_collection( + self, pytester: Pytester + ) -> None: """Integration test for issue #995.""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1022,7 +1044,7 @@ class TestTracebackCutting: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret != 0 out = result.stdout.str() assert "INTERNALERROR>" not in out @@ -1039,6 +1061,7 @@ class TestTracebackCutting: """ from _pytest._code import filter_traceback + tb = None try: ns: Dict[str, Any] = {} exec("def foo(): raise ValueError", ns) @@ -1051,7 +1074,7 @@ class TestTracebackCutting: assert isinstance(traceback[-1].path, str) assert not filter_traceback(traceback[-1]) - def test_filter_traceback_path_no_longer_valid(self, testdir) -> None: + def test_filter_traceback_path_no_longer_valid(self, pytester: Pytester) -> None: """Test that filter_traceback() works with the fact that _pytest._code.code.Code.path attribute might return an str object. @@ -1060,13 +1083,14 @@ class TestTracebackCutting: """ from _pytest._code import filter_traceback - testdir.syspathinsert() - testdir.makepyfile( + pytester.syspathinsert() + pytester.makepyfile( filter_traceback_entry_as_str=""" def foo(): raise ValueError """ ) + tb = None try: import filter_traceback_entry_as_str @@ -1075,15 +1099,15 @@ class TestTracebackCutting: _, _, tb = sys.exc_info() assert tb is not None - testdir.tmpdir.join("filter_traceback_entry_as_str.py").remove() + pytester.path.joinpath("filter_traceback_entry_as_str.py").unlink() traceback = _pytest._code.Traceback(tb) assert isinstance(traceback[-1].path, str) assert filter_traceback(traceback[-1]) class TestReportInfo: - def test_itemreport_reportinfo(self, testdir): - testdir.makeconftest( + def test_itemreport_reportinfo(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest class MyFunction(pytest.Function): @@ -1094,26 +1118,27 @@ class TestReportInfo: return MyFunction.from_parent(name=name, parent=collector) """ ) - item = testdir.getitem("def test_func(): pass") + item = pytester.getitem("def test_func(): pass") item.config.pluginmanager.getplugin("runner") assert item.location == ("ABCDE", 42, "custom") - def test_func_reportinfo(self, testdir): - item = testdir.getitem("def test_func(): pass") + def test_func_reportinfo(self, pytester: Pytester) -> None: + item = pytester.getitem("def test_func(): pass") fspath, lineno, modpath = item.reportinfo() assert fspath == item.fspath assert lineno == 0 assert modpath == "test_func" - def test_class_reportinfo(self, testdir): - modcol = testdir.getmodulecol( + def test_class_reportinfo(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ # lineno 0 class TestClass(object): def test_hello(self): pass """ ) - classcol = testdir.collect_by_name(modcol, "TestClass") + classcol = pytester.collect_by_name(modcol, "TestClass") + assert isinstance(classcol, Class) fspath, lineno, msg = classcol.reportinfo() assert fspath == modcol.fspath assert lineno == 1 @@ -1122,26 +1147,28 @@ class TestReportInfo: @pytest.mark.filterwarnings( "ignore:usage of Generator.Function is deprecated, please use pytest.Function instead" ) - def test_reportinfo_with_nasty_getattr(self, testdir): + def test_reportinfo_with_nasty_getattr(self, pytester: Pytester) -> None: # https://github.com/pytest-dev/pytest/issues/1204 - modcol = testdir.getmodulecol( + modcol = pytester.getmodulecol( """ # lineno 0 class TestClass(object): def __getattr__(self, name): return "this is not an int" - def test_foo(self): + def intest_foo(self): pass """ ) - classcol = testdir.collect_by_name(modcol, "TestClass") - instance = classcol.collect()[0] + classcol = pytester.collect_by_name(modcol, "TestClass") + assert isinstance(classcol, Class) + instance = list(classcol.collect())[0] + assert isinstance(instance, Instance) fspath, lineno, msg = instance.reportinfo() -def test_customized_python_discovery(testdir): - testdir.makeini( +def test_customized_python_discovery(pytester: Pytester) -> None: + pytester.makeini( """ [pytest] python_files=check_*.py @@ -1149,7 +1176,7 @@ def test_customized_python_discovery(testdir): python_functions=check """ ) - p = testdir.makepyfile( + p = pytester.makepyfile( """ def check_simple(): pass @@ -1158,41 +1185,41 @@ def test_customized_python_discovery(testdir): pass """ ) - p2 = p.new(basename=p.basename.replace("test", "check")) - p.move(p2) - result = testdir.runpytest("--collect-only", "-s") + p2 = p.with_name(p.name.replace("test", "check")) + p.rename(p2) + result = pytester.runpytest("--collect-only", "-s") result.stdout.fnmatch_lines( ["*check_customized*", "*check_simple*", "*CheckMyApp*", "*check_meth*"] ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 result.stdout.fnmatch_lines(["*2 passed*"]) -def test_customized_python_discovery_functions(testdir): - testdir.makeini( +def test_customized_python_discovery_functions(pytester: Pytester) -> None: + pytester.makeini( """ [pytest] python_functions=_test """ ) - testdir.makepyfile( + pytester.makepyfile( """ def _test_underscore(): pass """ ) - result = testdir.runpytest("--collect-only", "-s") + result = pytester.runpytest("--collect-only", "-s") result.stdout.fnmatch_lines(["*_test_underscore*"]) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 result.stdout.fnmatch_lines(["*1 passed*"]) -def test_unorderable_types(testdir): - testdir.makepyfile( +def test_unorderable_types(pytester: Pytester) -> None: + pytester.makepyfile( """ class TestJoinEmpty(object): pass @@ -1205,19 +1232,19 @@ def test_unorderable_types(testdir): TestFoo = make_test() """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.no_fnmatch_line("*TypeError*") assert result.ret == ExitCode.NO_TESTS_COLLECTED @pytest.mark.filterwarnings("default") -def test_dont_collect_non_function_callable(testdir): +def test_dont_collect_non_function_callable(pytester: Pytester) -> None: """Test for issue https://github.com/pytest-dev/pytest/issues/331 In this case an INTERNALERROR occurred trying to report the failure of a test like this one because pytest failed to get the source lines. """ - testdir.makepyfile( + pytester.makepyfile( """ class Oh(object): def __call__(self): @@ -1229,7 +1256,7 @@ def test_dont_collect_non_function_callable(testdir): pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*collected 1 item*", @@ -1239,21 +1266,21 @@ def test_dont_collect_non_function_callable(testdir): ) -def test_class_injection_does_not_break_collection(testdir): +def test_class_injection_does_not_break_collection(pytester: Pytester) -> None: """Tests whether injection during collection time will terminate testing. In this case the error should not occur if the TestClass itself is modified during collection time, and the original method list is still used for collection. """ - testdir.makeconftest( + pytester.makeconftest( """ from test_inject import TestClass def pytest_generate_tests(metafunc): TestClass.changed_var = {} """ ) - testdir.makepyfile( + pytester.makepyfile( test_inject=''' class TestClass(object): def test_injection(self): @@ -1261,7 +1288,7 @@ def test_class_injection_does_not_break_collection(testdir): pass ''' ) - result = testdir.runpytest() + result = pytester.runpytest() assert ( "RuntimeError: dictionary changed size during iteration" not in result.stdout.str() @@ -1269,16 +1296,16 @@ def test_class_injection_does_not_break_collection(testdir): result.stdout.fnmatch_lines(["*1 passed*"]) -def test_syntax_error_with_non_ascii_chars(testdir): +def test_syntax_error_with_non_ascii_chars(pytester: Pytester) -> None: """Fix decoding issue while formatting SyntaxErrors during collection (#578).""" - testdir.makepyfile("☃") - result = testdir.runpytest() + pytester.makepyfile("☃") + result = pytester.runpytest() result.stdout.fnmatch_lines(["*ERROR collecting*", "*SyntaxError*", "*1 error in*"]) -def test_collect_error_with_fulltrace(testdir): - testdir.makepyfile("assert 0") - result = testdir.runpytest("--fulltrace") +def test_collect_error_with_fulltrace(pytester: Pytester) -> None: + pytester.makepyfile("assert 0") + result = pytester.runpytest("--fulltrace") result.stdout.fnmatch_lines( [ "collected 0 items / 1 error", @@ -1295,14 +1322,14 @@ def test_collect_error_with_fulltrace(testdir): ) -def test_skip_duplicates_by_default(testdir): +def test_skip_duplicates_by_default(pytester: Pytester) -> None: """Test for issue https://github.com/pytest-dev/pytest/issues/1609 (#1609) Ignore duplicate directories. """ - a = testdir.mkdir("a") - fh = a.join("test_a.py") - fh.write( + a = pytester.mkdir("a") + fh = a.joinpath("test_a.py") + fh.write_text( textwrap.dedent( """\ import pytest @@ -1311,18 +1338,18 @@ def test_skip_duplicates_by_default(testdir): """ ) ) - result = testdir.runpytest(a.strpath, a.strpath) + result = pytester.runpytest(str(a), str(a)) result.stdout.fnmatch_lines(["*collected 1 item*"]) -def test_keep_duplicates(testdir): +def test_keep_duplicates(pytester: Pytester) -> None: """Test for issue https://github.com/pytest-dev/pytest/issues/1609 (#1609) Use --keep-duplicates to collect tests from duplicate directories. """ - a = testdir.mkdir("a") - fh = a.join("test_a.py") - fh.write( + a = pytester.mkdir("a") + fh = a.joinpath("test_a.py") + fh.write_text( textwrap.dedent( """\ import pytest @@ -1331,24 +1358,24 @@ def test_keep_duplicates(testdir): """ ) ) - result = testdir.runpytest("--keep-duplicates", a.strpath, a.strpath) + result = pytester.runpytest("--keep-duplicates", str(a), str(a)) result.stdout.fnmatch_lines(["*collected 2 item*"]) -def test_package_collection_infinite_recursion(testdir): - testdir.copy_example("collect/package_infinite_recursion") - result = testdir.runpytest() +def test_package_collection_infinite_recursion(pytester: Pytester) -> None: + pytester.copy_example("collect/package_infinite_recursion") + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) -def test_package_collection_init_given_as_argument(testdir): +def test_package_collection_init_given_as_argument(pytester: Pytester) -> None: """Regression test for #3749""" - p = testdir.copy_example("collect/package_init_given_as_arg") - result = testdir.runpytest(p / "pkg" / "__init__.py") + p = pytester.copy_example("collect/package_init_given_as_arg") + result = pytester.runpytest(p / "pkg" / "__init__.py") result.stdout.fnmatch_lines(["*1 passed*"]) -def test_package_with_modules(testdir): +def test_package_with_modules(pytester: Pytester) -> None: """ . └── root @@ -1363,32 +1390,35 @@ def test_package_with_modules(testdir): └── test_in_sub2.py """ - root = testdir.mkpydir("root") - sub1 = root.mkdir("sub1") - sub1.ensure("__init__.py") - sub1_test = sub1.mkdir("sub1_1") - sub1_test.ensure("__init__.py") - sub2 = root.mkdir("sub2") - sub2_test = sub2.mkdir("sub2") + root = pytester.mkpydir("root") + sub1 = root.joinpath("sub1") + sub1_test = sub1.joinpath("sub1_1") + sub1_test.mkdir(parents=True) + for d in (sub1, sub1_test): + d.joinpath("__init__.py").touch() - sub1_test.join("test_in_sub1.py").write("def test_1(): pass") - sub2_test.join("test_in_sub2.py").write("def test_2(): pass") + sub2 = root.joinpath("sub2") + sub2_test = sub2.joinpath("test") + sub2_test.mkdir(parents=True) + + sub1_test.joinpath("test_in_sub1.py").write_text("def test_1(): pass") + sub2_test.joinpath("test_in_sub2.py").write_text("def test_2(): pass") # Execute from . - result = testdir.runpytest("-v", "-s") + result = pytester.runpytest("-v", "-s") result.assert_outcomes(passed=2) # Execute from . with one argument "root" - result = testdir.runpytest("-v", "-s", "root") + result = pytester.runpytest("-v", "-s", "root") result.assert_outcomes(passed=2) # Chdir into package's root and execute with no args - root.chdir() - result = testdir.runpytest("-v", "-s") + os.chdir(root) + result = pytester.runpytest("-v", "-s") result.assert_outcomes(passed=2) -def test_package_ordering(testdir): +def test_package_ordering(pytester: Pytester) -> None: """ . └── root @@ -1402,22 +1432,24 @@ def test_package_ordering(testdir): └── test_sub2.py """ - testdir.makeini( + pytester.makeini( """ [pytest] python_files=*.py """ ) - root = testdir.mkpydir("root") - sub1 = root.mkdir("sub1") - sub1.ensure("__init__.py") - sub2 = root.mkdir("sub2") - sub2_test = sub2.mkdir("sub2") + root = pytester.mkpydir("root") + sub1 = root.joinpath("sub1") + sub1.mkdir() + sub1.joinpath("__init__.py").touch() + sub2 = root.joinpath("sub2") + sub2_test = sub2.joinpath("test") + sub2_test.mkdir(parents=True) - root.join("Test_root.py").write("def test_1(): pass") - sub1.join("Test_sub1.py").write("def test_2(): pass") - sub2_test.join("test_sub2.py").write("def test_3(): pass") + root.joinpath("Test_root.py").write_text("def test_1(): pass") + sub1.joinpath("Test_sub1.py").write_text("def test_2(): pass") + sub2_test.joinpath("test_sub2.py").write_text("def test_3(): pass") # Execute from . - result = testdir.runpytest("-v", "-s") + result = pytester.runpytest("-v", "-s") result.assert_outcomes(passed=3) diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index ac62de608..862a65abe 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -1,3 +1,4 @@ +import os import sys import textwrap from pathlib import Path @@ -7,9 +8,10 @@ from _pytest import fixtures from _pytest.compat import getfuncargnames from _pytest.config import ExitCode from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch from _pytest.pytester import get_public_names from _pytest.pytester import Pytester -from _pytest.pytester import Testdir +from _pytest.python import Function def test_getfuncargnames_functions(): @@ -91,9 +93,9 @@ class TestFillFixtures: # used by oejskit, kept for compatibility assert pytest._fillfuncargs == fixtures._fillfuncargs - def test_funcarg_lookupfails(self, testdir): - testdir.copy_example() - result = testdir.runpytest() # "--collect-only") + def test_funcarg_lookupfails(self, pytester: Pytester) -> None: + pytester.copy_example() + result = pytester.runpytest() # "--collect-only") assert result.ret != 0 result.stdout.fnmatch_lines( """ @@ -103,60 +105,63 @@ class TestFillFixtures: """ ) - def test_detect_recursive_dependency_error(self, testdir): - testdir.copy_example() - result = testdir.runpytest() + def test_detect_recursive_dependency_error(self, pytester: Pytester) -> None: + pytester.copy_example() + result = pytester.runpytest() result.stdout.fnmatch_lines( ["*recursive dependency involving fixture 'fix1' detected*"] ) - def test_funcarg_basic(self, testdir): - testdir.copy_example() - item = testdir.getitem(Path("test_funcarg_basic.py")) + def test_funcarg_basic(self, pytester: Pytester) -> None: + pytester.copy_example() + item = pytester.getitem(Path("test_funcarg_basic.py")) + assert isinstance(item, Function) item._request._fillfixtures() del item.funcargs["request"] assert len(get_public_names(item.funcargs)) == 2 assert item.funcargs["some"] == "test_func" assert item.funcargs["other"] == 42 - def test_funcarg_lookup_modulelevel(self, testdir): - testdir.copy_example() - reprec = testdir.inline_run() + def test_funcarg_lookup_modulelevel(self, pytester: Pytester) -> None: + pytester.copy_example() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_funcarg_lookup_classlevel(self, testdir): - p = testdir.copy_example() - result = testdir.runpytest(p) + def test_funcarg_lookup_classlevel(self, pytester: Pytester) -> None: + p = pytester.copy_example() + result = pytester.runpytest(p) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_conftest_funcargs_only_available_in_subdir(self, testdir): - testdir.copy_example() - result = testdir.runpytest("-v") + def test_conftest_funcargs_only_available_in_subdir( + self, pytester: Pytester + ) -> None: + pytester.copy_example() + result = pytester.runpytest("-v") result.assert_outcomes(passed=2) - def test_extend_fixture_module_class(self, testdir): - testfile = testdir.copy_example() - result = testdir.runpytest() + def test_extend_fixture_module_class(self, pytester: Pytester) -> None: + testfile = pytester.copy_example() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_extend_fixture_conftest_module(self, testdir): - p = testdir.copy_example() - result = testdir.runpytest() + def test_extend_fixture_conftest_module(self, pytester: Pytester) -> None: + p = pytester.copy_example() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(str(next(Path(str(p)).rglob("test_*.py")))) + result = pytester.runpytest(str(next(Path(str(p)).rglob("test_*.py")))) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_extend_fixture_conftest_conftest(self, testdir): - p = testdir.copy_example() - result = testdir.runpytest() + def test_extend_fixture_conftest_conftest(self, pytester: Pytester) -> None: + p = pytester.copy_example() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(str(next(Path(str(p)).rglob("test_*.py")))) + result = pytester.runpytest(str(next(Path(str(p)).rglob("test_*.py")))) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_extend_fixture_conftest_plugin(self, testdir): - testdir.makepyfile( + def test_extend_fixture_conftest_plugin(self, pytester: Pytester) -> None: + pytester.makepyfile( testplugin=""" import pytest @@ -165,8 +170,8 @@ class TestFillFixtures: return 7 """ ) - testdir.syspathinsert() - testdir.makeconftest( + pytester.syspathinsert() + pytester.makeconftest( """ import pytest @@ -177,18 +182,18 @@ class TestFillFixtures: return foo + 7 """ ) - testdir.makepyfile( + pytester.makepyfile( """ def test_foo(foo): assert foo == 14 """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") assert result.ret == 0 - def test_extend_fixture_plugin_plugin(self, testdir): + def test_extend_fixture_plugin_plugin(self, pytester: Pytester) -> None: # Two plugins should extend each order in loading order - testdir.makepyfile( + pytester.makepyfile( testplugin0=""" import pytest @@ -197,7 +202,7 @@ class TestFillFixtures: return 7 """ ) - testdir.makepyfile( + pytester.makepyfile( testplugin1=""" import pytest @@ -206,8 +211,8 @@ class TestFillFixtures: return foo + 7 """ ) - testdir.syspathinsert() - testdir.makepyfile( + pytester.syspathinsert() + pytester.makepyfile( """ pytest_plugins = ['testplugin0', 'testplugin1'] @@ -215,12 +220,14 @@ class TestFillFixtures: assert foo == 14 """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 - def test_override_parametrized_fixture_conftest_module(self, testdir): + def test_override_parametrized_fixture_conftest_module( + self, pytester: Pytester + ) -> None: """Test override of the parametrized fixture with non-parametrized one on the test module level.""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -229,7 +236,7 @@ class TestFillFixtures: return request.param """ ) - testfile = testdir.makepyfile( + testfile = pytester.makepyfile( """ import pytest @@ -241,14 +248,16 @@ class TestFillFixtures: assert spam == 'spam' """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_override_parametrized_fixture_conftest_conftest(self, testdir): + def test_override_parametrized_fixture_conftest_conftest( + self, pytester: Pytester + ) -> None: """Test override of the parametrized fixture with non-parametrized one on the conftest level.""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -257,8 +266,8 @@ class TestFillFixtures: return request.param """ ) - subdir = testdir.mkpydir("subdir") - subdir.join("conftest.py").write( + subdir = pytester.mkpydir("subdir") + subdir.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -269,8 +278,8 @@ class TestFillFixtures: """ ) ) - testfile = subdir.join("test_spam.py") - testfile.write( + testfile = subdir.joinpath("test_spam.py") + testfile.write_text( textwrap.dedent( """\ def test_spam(spam): @@ -278,14 +287,16 @@ class TestFillFixtures: """ ) ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*1 passed*"]) - def test_override_non_parametrized_fixture_conftest_module(self, testdir): + def test_override_non_parametrized_fixture_conftest_module( + self, pytester: Pytester + ) -> None: """Test override of the non-parametrized fixture with parametrized one on the test module level.""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -294,7 +305,7 @@ class TestFillFixtures: return 'spam' """ ) - testfile = testdir.makepyfile( + testfile = pytester.makepyfile( """ import pytest @@ -309,14 +320,16 @@ class TestFillFixtures: params['spam'] += 1 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*3 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*3 passed*"]) - def test_override_non_parametrized_fixture_conftest_conftest(self, testdir): + def test_override_non_parametrized_fixture_conftest_conftest( + self, pytester: Pytester + ) -> None: """Test override of the non-parametrized fixture with parametrized one on the conftest level.""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -325,8 +338,8 @@ class TestFillFixtures: return 'spam' """ ) - subdir = testdir.mkpydir("subdir") - subdir.join("conftest.py").write( + subdir = pytester.mkpydir("subdir") + subdir.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -337,8 +350,8 @@ class TestFillFixtures: """ ) ) - testfile = subdir.join("test_spam.py") - testfile.write( + testfile = subdir.joinpath("test_spam.py") + testfile.write_text( textwrap.dedent( """\ params = {'spam': 1} @@ -349,18 +362,18 @@ class TestFillFixtures: """ ) ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*3 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*3 passed*"]) def test_override_autouse_fixture_with_parametrized_fixture_conftest_conftest( - self, testdir - ): + self, pytester: Pytester + ) -> None: """Test override of the autouse fixture with parametrized one on the conftest level. This test covers the issue explained in issue 1601 """ - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -369,8 +382,8 @@ class TestFillFixtures: return 'spam' """ ) - subdir = testdir.mkpydir("subdir") - subdir.join("conftest.py").write( + subdir = pytester.mkpydir("subdir") + subdir.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -381,8 +394,8 @@ class TestFillFixtures: """ ) ) - testfile = subdir.join("test_spam.py") - testfile.write( + testfile = subdir.joinpath("test_spam.py") + testfile.write_text( textwrap.dedent( """\ params = {'spam': 1} @@ -393,16 +406,18 @@ class TestFillFixtures: """ ) ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*3 passed*"]) - result = testdir.runpytest(testfile) + result = pytester.runpytest(testfile) result.stdout.fnmatch_lines(["*3 passed*"]) - def test_override_fixture_reusing_super_fixture_parametrization(self, testdir): + def test_override_fixture_reusing_super_fixture_parametrization( + self, pytester: Pytester + ) -> None: """Override a fixture at a lower level, reusing the higher-level fixture that is parametrized (#1953). """ - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -411,7 +426,7 @@ class TestFillFixtures: return request.param """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -423,14 +438,16 @@ class TestFillFixtures: assert foo in (2, 4) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 passed*"]) - def test_override_parametrize_fixture_and_indirect(self, testdir): + def test_override_parametrize_fixture_and_indirect( + self, pytester: Pytester + ) -> None: """Override a fixture at a lower level, reusing the higher-level fixture that is parametrized, while also using indirect parametrization. """ - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -439,7 +456,7 @@ class TestFillFixtures: return request.param """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -457,14 +474,14 @@ class TestFillFixtures: assert foo in (2, 4) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 passed*"]) def test_override_top_level_fixture_reusing_super_fixture_parametrization( - self, testdir - ): + self, pytester: Pytester + ) -> None: """Same as the above test, but with another level of overwriting.""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -473,7 +490,7 @@ class TestFillFixtures: return request.param """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -491,15 +508,17 @@ class TestFillFixtures: assert foo in (2, 4) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 passed*"]) - def test_override_parametrized_fixture_with_new_parametrized_fixture(self, testdir): + def test_override_parametrized_fixture_with_new_parametrized_fixture( + self, pytester: Pytester + ) -> None: """Overriding a parametrized fixture, while also parametrizing the new fixture and simultaneously requesting the overwritten fixture as parameter, yields the same value as ``request.param``. """ - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -508,7 +527,7 @@ class TestFillFixtures: return request.param """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -521,13 +540,13 @@ class TestFillFixtures: assert foo in (20, 40) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 passed*"]) - def test_autouse_fixture_plugin(self, testdir): + def test_autouse_fixture_plugin(self, pytester: Pytester) -> None: # A fixture from a plugin has no baseid set, which screwed up # the autouse fixture handling. - testdir.makepyfile( + pytester.makepyfile( testplugin=""" import pytest @@ -536,8 +555,8 @@ class TestFillFixtures: request.function.foo = 7 """ ) - testdir.syspathinsert() - testdir.makepyfile( + pytester.syspathinsert() + pytester.makepyfile( """ pytest_plugins = 'testplugin' @@ -545,11 +564,11 @@ class TestFillFixtures: assert request.function.foo == 7 """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 - def test_funcarg_lookup_error(self, testdir): - testdir.makeconftest( + def test_funcarg_lookup_error(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @@ -566,13 +585,13 @@ class TestFillFixtures: def d_fixture(): pass """ ) - testdir.makepyfile( + pytester.makepyfile( """ def test_lookup_error(unknown): pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*ERROR at setup of test_lookup_error*", @@ -586,9 +605,9 @@ class TestFillFixtures: ) result.stdout.no_fnmatch_line("*INTERNAL*") - def test_fixture_excinfo_leak(self, testdir): + def test_fixture_excinfo_leak(self, pytester: Pytester) -> None: # on python2 sys.excinfo would leak into fixture executions - testdir.makepyfile( + pytester.makepyfile( """ import sys import traceback @@ -607,13 +626,13 @@ class TestFillFixtures: assert sys.exc_info() == (None, None, None) """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 0 class TestRequestBasic: - def test_request_attributes(self, testdir): - item = testdir.getitem( + def test_request_attributes(self, pytester: Pytester) -> None: + item = pytester.getitem( """ import pytest @@ -622,6 +641,7 @@ class TestRequestBasic: def test_func(something): pass """ ) + assert isinstance(item, Function) req = fixtures.FixtureRequest(item, _ispytest=True) assert req.function == item.obj assert req.keywords == item.keywords @@ -631,8 +651,8 @@ class TestRequestBasic: assert req.config == item.config assert repr(req).find(req.function.__name__) != -1 - def test_request_attributes_method(self, testdir): - (item,) = testdir.getitems( + def test_request_attributes_method(self, pytester: Pytester) -> None: + (item,) = pytester.getitems( """ import pytest class TestB(object): @@ -644,12 +664,13 @@ class TestRequestBasic: pass """ ) + assert isinstance(item, Function) req = item._request assert req.cls.__name__ == "TestB" assert req.instance.__class__ == req.cls - def test_request_contains_funcarg_arg2fixturedefs(self, testdir): - modcol = testdir.getmodulecol( + def test_request_contains_funcarg_arg2fixturedefs(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol( """ import pytest @pytest.fixture @@ -660,7 +681,7 @@ class TestRequestBasic: pass """ ) - (item1,) = testdir.genitems([modcol]) + (item1,) = pytester.genitems([modcol]) assert item1.name == "test_method" arg2fixturedefs = fixtures.FixtureRequest( item1, _ispytest=True @@ -672,14 +693,14 @@ class TestRequestBasic: hasattr(sys, "pypy_version_info"), reason="this method of test doesn't work on pypy", ) - def test_request_garbage(self, testdir): + def test_request_garbage(self, pytester: Pytester) -> None: try: import xdist # noqa except ImportError: pass else: pytest.xfail("this test is flaky when executed with xdist") - testdir.makepyfile( + pytester.makepyfile( """ import sys import pytest @@ -705,11 +726,11 @@ class TestRequestBasic: pass """ ) - result = testdir.runpytest_subprocess() + result = pytester.runpytest_subprocess() result.stdout.fnmatch_lines(["* 1 passed in *"]) - def test_getfixturevalue_recursive(self, testdir): - testdir.makeconftest( + def test_getfixturevalue_recursive(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @@ -718,7 +739,7 @@ class TestRequestBasic: return 1 """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -729,10 +750,10 @@ class TestRequestBasic: assert something == 2 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_getfixturevalue_teardown(self, testdir): + def test_getfixturevalue_teardown(self, pytester: Pytester) -> None: """ Issue #1895 @@ -743,7 +764,7 @@ class TestRequestBasic: `inner` dependent on `resource` when it is used via `getfixturevalue`: `test_func` will then cause the `resource`'s finalizer to be called first because of this. """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -767,11 +788,11 @@ class TestRequestBasic: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed in *"]) - def test_getfixturevalue(self, testdir): - item = testdir.getitem( + def test_getfixturevalue(self, pytester: Pytester) -> None: + item = pytester.getitem( """ import pytest values = [2] @@ -783,6 +804,7 @@ class TestRequestBasic: def test_func(something): pass """ ) + assert isinstance(item, Function) req = item._request with pytest.raises(pytest.FixtureLookupError): @@ -800,8 +822,8 @@ class TestRequestBasic: assert len(get_public_names(item.funcargs)) == 2 assert "request" in item.funcargs - def test_request_addfinalizer(self, testdir): - item = testdir.getitem( + def test_request_addfinalizer(self, pytester: Pytester) -> None: + item = pytester.getitem( """ import pytest teardownlist = [] @@ -811,18 +833,21 @@ class TestRequestBasic: def test_func(something): pass """ ) + assert isinstance(item, Function) item.session._setupstate.prepare(item) item._request._fillfixtures() # successively check finalization calls - teardownlist = item.getparent(pytest.Module).obj.teardownlist + parent = item.getparent(pytest.Module) + assert parent is not None + teardownlist = parent.obj.teardownlist ss = item.session._setupstate assert not teardownlist ss.teardown_exact(item, None) print(ss.stack) assert teardownlist == [1] - def test_request_addfinalizer_failing_setup(self, testdir): - testdir.makepyfile( + def test_request_addfinalizer_failing_setup(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [1] @@ -836,11 +861,13 @@ class TestRequestBasic: assert not values """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(failed=1, passed=1) - def test_request_addfinalizer_failing_setup_module(self, testdir): - testdir.makepyfile( + def test_request_addfinalizer_failing_setup_module( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest values = [1, 2] @@ -853,12 +880,14 @@ class TestRequestBasic: pass """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") mod = reprec.getcalls("pytest_runtest_setup")[0].item.module assert not mod.values - def test_request_addfinalizer_partial_setup_failure(self, testdir): - p = testdir.makepyfile( + def test_request_addfinalizer_partial_setup_failure( + self, pytester: Pytester + ) -> None: + p = pytester.makepyfile( """ import pytest values = [] @@ -871,17 +900,19 @@ class TestRequestBasic: assert len(values) == 1 """ ) - result = testdir.runpytest(p) + result = pytester.runpytest(p) result.stdout.fnmatch_lines( ["*1 error*"] # XXX the whole module collection fails ) - def test_request_subrequest_addfinalizer_exceptions(self, testdir): + def test_request_subrequest_addfinalizer_exceptions( + self, pytester: Pytester + ) -> None: """ Ensure exceptions raised during teardown by a finalizer are suppressed until all finalizers are called, re-raising the first exception (#2440) """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest values = [] @@ -905,19 +936,19 @@ class TestRequestBasic: assert values == [3, 2, 1] """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( ["*Exception: Error in excepts fixture", "* 2 passed, 1 error in *"] ) - def test_request_getmodulepath(self, testdir): - modcol = testdir.getmodulecol("def test_somefunc(): pass") - (item,) = testdir.genitems([modcol]) + def test_request_getmodulepath(self, pytester: Pytester) -> None: + modcol = pytester.getmodulecol("def test_somefunc(): pass") + (item,) = pytester.genitems([modcol]) req = fixtures.FixtureRequest(item, _ispytest=True) assert req.fspath == modcol.fspath - def test_request_fixturenames(self, testdir): - testdir.makepyfile( + def test_request_fixturenames(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest from _pytest.pytester import get_public_names @@ -936,17 +967,17 @@ class TestRequestBasic: "tmp_path", "tmp_path_factory"]) """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_request_fixturenames_dynamic_fixture(self, testdir): + def test_request_fixturenames_dynamic_fixture(self, pytester: Pytester) -> None: """Regression test for #3057""" - testdir.copy_example("fixtures/test_getfixturevalue_dynamic.py") - result = testdir.runpytest() + pytester.copy_example("fixtures/test_getfixturevalue_dynamic.py") + result = pytester.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - def test_setupdecorator_and_xunit(self, testdir): - testdir.makepyfile( + def test_setupdecorator_and_xunit(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -974,13 +1005,14 @@ class TestRequestBasic: "function", "method", "function"] """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=3) - def test_fixtures_sub_subdir_normalize_sep(self, testdir): + def test_fixtures_sub_subdir_normalize_sep(self, pytester: Pytester) -> None: # this tests that normalization of nodeids takes place - b = testdir.mkdir("tests").mkdir("unit") - b.join("conftest.py").write( + b = pytester.path.joinpath("tests", "unit") + b.mkdir(parents=True) + b.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -990,9 +1022,9 @@ class TestRequestBasic: """ ) ) - p = b.join("test_module.py") - p.write("def test_func(arg1): pass") - result = testdir.runpytest(p, "--fixtures") + p = b.joinpath("test_module.py") + p.write_text("def test_func(arg1): pass") + result = pytester.runpytest(p, "--fixtures") assert result.ret == 0 result.stdout.fnmatch_lines( """ @@ -1001,13 +1033,13 @@ class TestRequestBasic: """ ) - def test_show_fixtures_color_yes(self, testdir): - testdir.makepyfile("def test_this(): assert 1") - result = testdir.runpytest("--color=yes", "--fixtures") + def test_show_fixtures_color_yes(self, pytester: Pytester) -> None: + pytester.makepyfile("def test_this(): assert 1") + result = pytester.runpytest("--color=yes", "--fixtures") assert "\x1b[32mtmpdir" in result.stdout.str() - def test_newstyle_with_request(self, testdir): - testdir.makepyfile( + def test_newstyle_with_request(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture() @@ -1017,11 +1049,11 @@ class TestRequestBasic: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_setupcontext_no_param(self, testdir): - testdir.makepyfile( + def test_setupcontext_no_param(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(params=[1,2]) @@ -1035,13 +1067,13 @@ class TestRequestBasic: assert arg in (1,2) """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) class TestRequestMarking: - def test_applymarker(self, testdir): - item1, item2 = testdir.getitems( + def test_applymarker(self, pytester: Pytester) -> None: + item1, item2 = pytester.getitems( """ import pytest @@ -1065,8 +1097,8 @@ class TestRequestMarking: with pytest.raises(ValueError): req1.applymarker(42) # type: ignore[arg-type] - def test_accesskeywords(self, testdir): - testdir.makepyfile( + def test_accesskeywords(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture() @@ -1078,11 +1110,11 @@ class TestRequestMarking: assert "abc" not in keywords """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_accessmarker_dynamic(self, testdir): - testdir.makeconftest( + def test_accessmarker_dynamic(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @pytest.fixture() @@ -1094,7 +1126,7 @@ class TestRequestMarking: request.applymarker(pytest.mark.XYZ("hello")) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest def test_fun1(keywords): @@ -1105,13 +1137,13 @@ class TestRequestMarking: assert "abc" not in keywords """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) class TestFixtureUsages: - def test_noargfixturedec(self, testdir): - testdir.makepyfile( + def test_noargfixturedec(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture @@ -1122,11 +1154,11 @@ class TestFixtureUsages: assert arg1 == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_receives_funcargs(self, testdir): - testdir.makepyfile( + def test_receives_funcargs(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture() @@ -1144,11 +1176,11 @@ class TestFixtureUsages: assert arg2 == 2 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_receives_funcargs_scope_mismatch(self, testdir): - testdir.makepyfile( + def test_receives_funcargs_scope_mismatch(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="function") @@ -1163,7 +1195,7 @@ class TestFixtureUsages: assert arg2 == 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*ScopeMismatch*involved factories*", @@ -1173,8 +1205,10 @@ class TestFixtureUsages: ] ) - def test_receives_funcargs_scope_mismatch_issue660(self, testdir): - testdir.makepyfile( + def test_receives_funcargs_scope_mismatch_issue660( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="function") @@ -1189,13 +1223,13 @@ class TestFixtureUsages: assert arg2 == 2 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( ["*ScopeMismatch*involved factories*", "* def arg2*", "*1 error*"] ) - def test_invalid_scope(self, testdir): - testdir.makepyfile( + def test_invalid_scope(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="functions") @@ -1206,14 +1240,14 @@ class TestFixtureUsages: pass """ ) - result = testdir.runpytest_inprocess() + result = pytester.runpytest_inprocess() result.stdout.fnmatch_lines( "*Fixture 'badscope' from test_invalid_scope.py got an unexpected scope value 'functions'" ) @pytest.mark.parametrize("scope", ["function", "session"]) - def test_parameters_without_eq_semantics(self, scope, testdir): - testdir.makepyfile( + def test_parameters_without_eq_semantics(self, scope, pytester: Pytester) -> None: + pytester.makepyfile( """ class NoEq1: # fails on `a == b` statement def __eq__(self, _): @@ -1240,11 +1274,11 @@ class TestFixtureUsages: scope=scope ) ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*4 passed*"]) - def test_funcarg_parametrized_and_used_twice(self, testdir): - testdir.makepyfile( + def test_funcarg_parametrized_and_used_twice(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -1262,11 +1296,13 @@ class TestFixtureUsages: assert len(values) == arg1 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 passed*"]) - def test_factory_uses_unknown_funcarg_as_dependency_error(self, testdir): - testdir.makepyfile( + def test_factory_uses_unknown_funcarg_as_dependency_error( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest @@ -1282,7 +1318,7 @@ class TestFixtureUsages: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( """ *pytest.fixture()* @@ -1293,8 +1329,8 @@ class TestFixtureUsages: """ ) - def test_factory_setup_as_classes_fails(self, testdir): - testdir.makepyfile( + def test_factory_setup_as_classes_fails(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest class arg1(object): @@ -1304,12 +1340,12 @@ class TestFixtureUsages: """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() values = reprec.getfailedcollections() assert len(values) == 1 - def test_usefixtures_marker(self, testdir): - testdir.makepyfile( + def test_usefixtures_marker(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1330,17 +1366,17 @@ class TestFixtureUsages: pytest.mark.usefixtures("myfix")(TestClass) """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_usefixtures_ini(self, testdir): - testdir.makeini( + def test_usefixtures_ini(self, pytester: Pytester) -> None: + pytester.makeini( """ [pytest] usefixtures = myfix """ ) - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -1350,7 +1386,7 @@ class TestFixtureUsages: """ ) - testdir.makepyfile( + pytester.makepyfile( """ class TestClass(object): def test_one(self): @@ -1359,19 +1395,19 @@ class TestFixtureUsages: assert self.hello == "world" """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_usefixtures_seen_in_showmarkers(self, testdir): - result = testdir.runpytest("--markers") + def test_usefixtures_seen_in_showmarkers(self, pytester: Pytester) -> None: + result = pytester.runpytest("--markers") result.stdout.fnmatch_lines( """ *usefixtures(fixturename1*mark tests*fixtures* """ ) - def test_request_instance_issue203(self, testdir): - testdir.makepyfile( + def test_request_instance_issue203(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1384,11 +1420,11 @@ class TestFixtureUsages: assert self.arg1 == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_fixture_parametrized_with_iterator(self, testdir): - testdir.makepyfile( + def test_fixture_parametrized_with_iterator(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1411,14 +1447,14 @@ class TestFixtureUsages: values.append(arg2*10) """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=4) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values assert values == [1, 2, 10, 20] - def test_setup_functions_as_fixtures(self, testdir): + def test_setup_functions_as_fixtures(self, pytester: Pytester) -> None: """Ensure setup_* methods obey fixture scope rules (#517, #3094).""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1452,15 +1488,14 @@ class TestFixtureUsages: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed in *"]) class TestFixtureManagerParseFactories: @pytest.fixture - def testdir(self, request): - testdir = request.getfixturevalue("testdir") - testdir.makeconftest( + def pytester(self, pytester: Pytester) -> Pytester: + pytester.makeconftest( """ import pytest @@ -1477,10 +1512,10 @@ class TestFixtureManagerParseFactories: return request._pyfuncitem """ ) - return testdir + return pytester - def test_parsefactories_evil_objects_issue214(self, testdir): - testdir.makepyfile( + def test_parsefactories_evil_objects_issue214(self, pytester: Pytester) -> None: + pytester.makepyfile( """ class A(object): def __call__(self): @@ -1492,11 +1527,11 @@ class TestFixtureManagerParseFactories: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1, failed=0) - def test_parsefactories_conftest(self, testdir): - testdir.makepyfile( + def test_parsefactories_conftest(self, pytester: Pytester) -> None: + pytester.makepyfile( """ def test_hello(item, fm): for name in ("fm", "hello", "item"): @@ -1506,11 +1541,13 @@ class TestFixtureManagerParseFactories: assert fac.func.__name__ == name """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=1) - def test_parsefactories_conftest_and_module_and_class(self, testdir): - testdir.makepyfile( + def test_parsefactories_conftest_and_module_and_class( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """\ import pytest @@ -1531,15 +1568,17 @@ class TestFixtureManagerParseFactories: assert faclist[2].func(item._request) == "class" """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=1) - def test_parsefactories_relative_node_ids(self, testdir): + def test_parsefactories_relative_node_ids( + self, pytester: Pytester, monkeypatch: MonkeyPatch + ) -> None: # example mostly taken from: # https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html - runner = testdir.mkdir("runner") - package = testdir.mkdir("package") - package.join("conftest.py").write( + runner = pytester.mkdir("runner") + package = pytester.mkdir("package") + package.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -1549,7 +1588,7 @@ class TestFixtureManagerParseFactories: """ ) ) - package.join("test_x.py").write( + package.joinpath("test_x.py").write_text( textwrap.dedent( """\ def test_x(one): @@ -1557,9 +1596,10 @@ class TestFixtureManagerParseFactories: """ ) ) - sub = package.mkdir("sub") - sub.join("__init__.py").ensure() - sub.join("conftest.py").write( + sub = package.joinpath("sub") + sub.mkdir() + sub.joinpath("__init__.py").touch() + sub.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -1569,7 +1609,7 @@ class TestFixtureManagerParseFactories: """ ) ) - sub.join("test_y.py").write( + sub.joinpath("test_y.py").write_text( textwrap.dedent( """\ def test_x(one): @@ -1577,20 +1617,21 @@ class TestFixtureManagerParseFactories: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - with runner.as_cwd(): - reprec = testdir.inline_run("..") + with monkeypatch.context() as mp: + mp.chdir(runner) + reprec = pytester.inline_run("..") reprec.assertoutcome(passed=2) - def test_package_xunit_fixture(self, testdir): - testdir.makepyfile( + def test_package_xunit_fixture(self, pytester: Pytester) -> None: + pytester.makepyfile( __init__="""\ values = [] """ ) - package = testdir.mkdir("package") - package.join("__init__.py").write( + package = pytester.mkdir("package") + package.joinpath("__init__.py").write_text( textwrap.dedent( """\ from .. import values @@ -1601,7 +1642,7 @@ class TestFixtureManagerParseFactories: """ ) ) - package.join("test_x.py").write( + package.joinpath("test_x.py").write_text( textwrap.dedent( """\ from .. import values @@ -1610,8 +1651,8 @@ class TestFixtureManagerParseFactories: """ ) ) - package = testdir.mkdir("package2") - package.join("__init__.py").write( + package = pytester.mkdir("package2") + package.joinpath("__init__.py").write_text( textwrap.dedent( """\ from .. import values @@ -1622,7 +1663,7 @@ class TestFixtureManagerParseFactories: """ ) ) - package.join("test_x.py").write( + package.joinpath("test_x.py").write_text( textwrap.dedent( """\ from .. import values @@ -1631,19 +1672,19 @@ class TestFixtureManagerParseFactories: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_package_fixture_complex(self, testdir): - testdir.makepyfile( + def test_package_fixture_complex(self, pytester: Pytester) -> None: + pytester.makepyfile( __init__="""\ values = [] """ ) - testdir.syspathinsert(testdir.tmpdir.dirname) - package = testdir.mkdir("package") - package.join("__init__.py").write("") - package.join("conftest.py").write( + pytester.syspathinsert(pytester.path.name) + package = pytester.mkdir("package") + package.joinpath("__init__.py").write_text("") + package.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -1661,7 +1702,7 @@ class TestFixtureManagerParseFactories: """ ) ) - package.join("test_x.py").write( + package.joinpath("test_x.py").write_text( textwrap.dedent( """\ from .. import values @@ -1672,19 +1713,19 @@ class TestFixtureManagerParseFactories: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_collect_custom_items(self, testdir): - testdir.copy_example("fixtures/custom_item") - result = testdir.runpytest("foo") + def test_collect_custom_items(self, pytester: Pytester) -> None: + pytester.copy_example("fixtures/custom_item") + result = pytester.runpytest("foo") result.stdout.fnmatch_lines(["*passed*"]) class TestAutouseDiscovery: @pytest.fixture - def testdir(self, testdir): - testdir.makeconftest( + def pytester(self, pytester: Pytester) -> Pytester: + pytester.makeconftest( """ import pytest @pytest.fixture(autouse=True) @@ -1707,10 +1748,10 @@ class TestAutouseDiscovery: return request._pyfuncitem """ ) - return testdir + return pytester - def test_parsefactories_conftest(self, testdir): - testdir.makepyfile( + def test_parsefactories_conftest(self, pytester: Pytester) -> None: + pytester.makepyfile( """ from _pytest.pytester import get_public_names def test_check_setup(item, fm): @@ -1720,11 +1761,11 @@ class TestAutouseDiscovery: assert "perfunction" in autousenames """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=1) - def test_two_classes_separated_autouse(self, testdir): - testdir.makepyfile( + def test_two_classes_separated_autouse(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest class TestA(object): @@ -1743,11 +1784,11 @@ class TestAutouseDiscovery: assert self.values == [1] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_setup_at_classlevel(self, testdir): - testdir.makepyfile( + def test_setup_at_classlevel(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest class TestClass(object): @@ -1760,12 +1801,12 @@ class TestAutouseDiscovery: assert self.funcname == "test_method2" """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=2) @pytest.mark.xfail(reason="'enabled' feature not implemented") - def test_setup_enabled_functionnode(self, testdir): - testdir.makepyfile( + def test_setup_enabled_functionnode(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1788,13 +1829,13 @@ class TestAutouseDiscovery: assert "db" in request.fixturenames """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=2) - def test_callables_nocode(self, testdir): + def test_callables_nocode(self, pytester: Pytester) -> None: """An imported mock.call would break setup/factory discovery due to it being callable and __code__ not being a code object.""" - testdir.makepyfile( + pytester.makepyfile( """ class _call(tuple): def __call__(self, *k, **kw): @@ -1805,13 +1846,13 @@ class TestAutouseDiscovery: call = _call() """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(failed=0, passed=0) - def test_autouse_in_conftests(self, testdir): - a = testdir.mkdir("a") - b = testdir.mkdir("a1") - conftest = testdir.makeconftest( + def test_autouse_in_conftests(self, pytester: Pytester) -> None: + a = pytester.mkdir("a") + b = pytester.mkdir("a1") + conftest = pytester.makeconftest( """ import pytest @pytest.fixture(autouse=True) @@ -1819,18 +1860,18 @@ class TestAutouseDiscovery: xxx """ ) - conftest.move(a.join(conftest.basename)) - a.join("test_something.py").write("def test_func(): pass") - b.join("test_otherthing.py").write("def test_func(): pass") - result = testdir.runpytest() + conftest.rename(a.joinpath(conftest.name)) + a.joinpath("test_something.py").write_text("def test_func(): pass") + b.joinpath("test_otherthing.py").write_text("def test_func(): pass") + result = pytester.runpytest() result.stdout.fnmatch_lines( """ *1 passed*1 error* """ ) - def test_autouse_in_module_and_two_classes(self, testdir): - testdir.makepyfile( + def test_autouse_in_module_and_two_classes(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -1851,14 +1892,14 @@ class TestAutouseDiscovery: assert values == ["module", "module", "A", "module"], values """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=3) class TestAutouseManagement: - def test_autouse_conftest_mid_directory(self, testdir): - pkgdir = testdir.mkpydir("xyz123") - pkgdir.join("conftest.py").write( + def test_autouse_conftest_mid_directory(self, pytester: Pytester) -> None: + pkgdir = pytester.mkpydir("xyz123") + pkgdir.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -1869,8 +1910,11 @@ class TestAutouseManagement: """ ) ) - t = pkgdir.ensure("tests", "test_app.py") - t.write( + sub = pkgdir.joinpath("tests") + sub.mkdir() + t = sub.joinpath("test_app.py") + t.touch() + t.write_text( textwrap.dedent( """\ import sys @@ -1879,11 +1923,11 @@ class TestAutouseManagement: """ ) ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=1) - def test_funcarg_and_setup(self, testdir): - testdir.makepyfile( + def test_funcarg_and_setup(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -1906,11 +1950,11 @@ class TestAutouseManagement: assert arg == 0 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_uses_parametrized_resource(self, testdir): - testdir.makepyfile( + def test_uses_parametrized_resource(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -1932,11 +1976,11 @@ class TestAutouseManagement: """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=2) - def test_session_parametrized_function(self, testdir): - testdir.makepyfile( + def test_session_parametrized_function(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1959,7 +2003,7 @@ class TestAutouseManagement: assert values[:arg] == [1,2][:arg] """ ) - reprec = testdir.inline_run("-v", "-s") + reprec = pytester.inline_run("-v", "-s") reprec.assertoutcome(passed=4) def test_class_function_parametrization_finalization( @@ -2007,8 +2051,8 @@ class TestAutouseManagement: ].values assert values == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2 - def test_scope_ordering(self, testdir): - testdir.makepyfile( + def test_scope_ordering(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2027,11 +2071,11 @@ class TestAutouseManagement: assert values == [1,3,2] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_parametrization_setup_teardown_ordering(self, testdir): - testdir.makepyfile( + def test_parametrization_setup_teardown_ordering(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2056,11 +2100,11 @@ class TestAutouseManagement: "setup-2", "step1-2", "step2-2", "teardown-2",] """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=5) - def test_ordering_autouse_before_explicit(self, testdir): - testdir.makepyfile( + def test_ordering_autouse_before_explicit(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -2075,14 +2119,16 @@ class TestAutouseManagement: assert values == [1,2] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) @pytest.mark.parametrize("param1", ["", "params=[1]"], ids=["p00", "p01"]) @pytest.mark.parametrize("param2", ["", "params=[1]"], ids=["p10", "p11"]) - def test_ordering_dependencies_torndown_first(self, testdir, param1, param2): + def test_ordering_dependencies_torndown_first( + self, pytester: Pytester, param1, param2 + ) -> None: """#226""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest values = [] @@ -2102,13 +2148,13 @@ class TestAutouseManagement: """ % locals() ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") reprec.assertoutcome(passed=2) class TestFixtureMarker: - def test_parametrize(self, testdir): - testdir.makepyfile( + def test_parametrize(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(params=["a", "b", "c"]) @@ -2121,11 +2167,11 @@ class TestFixtureMarker: assert values == list("abc") """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=4) - def test_multiple_parametrization_issue_736(self, testdir): - testdir.makepyfile( + def test_multiple_parametrization_issue_736(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -2139,19 +2185,21 @@ class TestFixtureMarker: assert foobar in [4,5,6] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=9) @pytest.mark.parametrize( "param_args", ["'fixt, val'", "'fixt,val'", "['fixt', 'val']", "('fixt', 'val')"], ) - def test_override_parametrized_fixture_issue_979(self, testdir, param_args): + def test_override_parametrized_fixture_issue_979( + self, pytester: Pytester, param_args + ) -> None: """Make sure a parametrized argument can override a parametrized fixture. This was a regression introduced in the fix for #736. """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -2165,11 +2213,11 @@ class TestFixtureMarker: """ % param_args ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_scope_session(self, testdir): - testdir.makepyfile( + def test_scope_session(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2189,11 +2237,11 @@ class TestFixtureMarker: assert len(values) == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=3) - def test_scope_session_exc(self, testdir): - testdir.makepyfile( + def test_scope_session_exc(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2210,11 +2258,11 @@ class TestFixtureMarker: assert values == [1] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(skipped=2, passed=1) - def test_scope_session_exc_two_fix(self, testdir): - testdir.makepyfile( + def test_scope_session_exc_two_fix(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2236,11 +2284,11 @@ class TestFixtureMarker: assert m == [] """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(skipped=2, passed=1) - def test_scope_exc(self, testdir): - testdir.makepyfile( + def test_scope_exc(self, pytester: Pytester) -> None: + pytester.makepyfile( test_foo=""" def test_foo(fix): pass @@ -2265,11 +2313,11 @@ class TestFixtureMarker: assert req_list == [1] """, ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(skipped=2, passed=1) - def test_scope_module_uses_session(self, testdir): - testdir.makepyfile( + def test_scope_module_uses_session(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2289,11 +2337,11 @@ class TestFixtureMarker: assert len(values) == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=3) - def test_scope_module_and_finalizer(self, testdir): - testdir.makeconftest( + def test_scope_module_and_finalizer(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest finalized_list = [] @@ -2311,7 +2359,7 @@ class TestFixtureMarker: return len(finalized_list) """ ) - testdir.makepyfile( + pytester.makepyfile( test_mod1=""" def test_1(arg, created, finalized): assert created == 1 @@ -2329,11 +2377,11 @@ class TestFixtureMarker: assert finalized == 2 """, ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=4) - def test_scope_mismatch_various(self, testdir): - testdir.makeconftest( + def test_scope_mismatch_various(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest finalized = [] @@ -2343,7 +2391,7 @@ class TestFixtureMarker: pass """ ) - testdir.makepyfile( + pytester.makepyfile( test_mod1=""" import pytest @pytest.fixture(scope="session") @@ -2353,14 +2401,14 @@ class TestFixtureMarker: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret != 0 result.stdout.fnmatch_lines( ["*ScopeMismatch*You tried*function*session*request*"] ) - def test_dynamic_scope(self, testdir): - testdir.makeconftest( + def test_dynamic_scope(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @@ -2383,7 +2431,7 @@ class TestFixtureMarker: """ ) - testdir.makepyfile( + pytester.makepyfile( """ def test_first(dynamic_fixture): assert dynamic_fixture == 1 @@ -2395,14 +2443,14 @@ class TestFixtureMarker: """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - reprec = testdir.inline_run("--extend-scope") + reprec = pytester.inline_run("--extend-scope") reprec.assertoutcome(passed=1, failed=1) - def test_dynamic_scope_bad_return(self, testdir): - testdir.makepyfile( + def test_dynamic_scope_bad_return(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -2415,14 +2463,14 @@ class TestFixtureMarker: """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( "Fixture 'fixture' from test_dynamic_scope_bad_return.py " "got an unexpected scope value 'wrong-scope'" ) - def test_register_only_with_mark(self, testdir): - testdir.makeconftest( + def test_register_only_with_mark(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @pytest.fixture() @@ -2430,7 +2478,7 @@ class TestFixtureMarker: return 1 """ ) - testdir.makepyfile( + pytester.makepyfile( test_mod1=""" import pytest @pytest.fixture() @@ -2440,11 +2488,11 @@ class TestFixtureMarker: assert arg == 2 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_parametrize_and_scope(self, testdir): - testdir.makepyfile( + def test_parametrize_and_scope(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="module", params=["a", "b", "c"]) @@ -2455,7 +2503,7 @@ class TestFixtureMarker: values.append(arg) """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=3) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values assert len(values) == 3 @@ -2463,8 +2511,8 @@ class TestFixtureMarker: assert "b" in values assert "c" in values - def test_scope_mismatch(self, testdir): - testdir.makeconftest( + def test_scope_mismatch(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @pytest.fixture(scope="function") @@ -2472,7 +2520,7 @@ class TestFixtureMarker: pass """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope="session") @@ -2482,11 +2530,11 @@ class TestFixtureMarker: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*ScopeMismatch*", "*1 error*"]) - def test_parametrize_separated_order(self, testdir): - testdir.makepyfile( + def test_parametrize_separated_order(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -2501,19 +2549,19 @@ class TestFixtureMarker: values.append(arg) """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=4) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values assert values == [1, 1, 2, 2] - def test_module_parametrized_ordering(self, testdir): - testdir.makeini( + def test_module_parametrized_ordering(self, pytester: Pytester) -> None: + pytester.makeini( """ [pytest] console_output_style=classic """ ) - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -2525,7 +2573,7 @@ class TestFixtureMarker: pass """ ) - testdir.makepyfile( + pytester.makepyfile( test_mod1=""" def test_func(sarg): pass @@ -2543,7 +2591,7 @@ class TestFixtureMarker: pass """, ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( """ test_mod1.py::test_func[s1] PASSED @@ -2565,14 +2613,14 @@ class TestFixtureMarker: """ ) - def test_dynamic_parametrized_ordering(self, testdir): - testdir.makeini( + def test_dynamic_parametrized_ordering(self, pytester: Pytester) -> None: + pytester.makeini( """ [pytest] console_output_style=classic """ ) - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -2592,7 +2640,7 @@ class TestFixtureMarker: pass """ ) - testdir.makepyfile( + pytester.makepyfile( """ def test(reprovision): pass @@ -2600,7 +2648,7 @@ class TestFixtureMarker: pass """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( """ test_dynamic_parametrized_ordering.py::test[flavor1-vxlan] PASSED @@ -2614,14 +2662,14 @@ class TestFixtureMarker: """ ) - def test_class_ordering(self, testdir): - testdir.makeini( + def test_class_ordering(self, pytester: Pytester) -> None: + pytester.makeini( """ [pytest] console_output_style=classic """ ) - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -2642,7 +2690,7 @@ class TestFixtureMarker: request.addfinalizer(fin) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -2656,7 +2704,7 @@ class TestFixtureMarker: pass """ ) - result = testdir.runpytest("-vs") + result = pytester.runpytest("-vs") result.stdout.re_match_lines( r""" test_class_ordering.py::TestClass2::test_1\[a-1\] PASSED @@ -2674,8 +2722,10 @@ class TestFixtureMarker: """ ) - def test_parametrize_separated_order_higher_scope_first(self, testdir): - testdir.makepyfile( + def test_parametrize_separated_order_higher_scope_first( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest @@ -2704,7 +2754,7 @@ class TestFixtureMarker: values.append("test4") """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=12) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values expected = [ @@ -2750,8 +2800,8 @@ class TestFixtureMarker: pprint.pprint(list(zip(values, expected))) assert values == expected - def test_parametrized_fixture_teardown_order(self, testdir): - testdir.makepyfile( + def test_parametrized_fixture_teardown_order(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(params=[1,2], scope="class") @@ -2783,7 +2833,7 @@ class TestFixtureMarker: assert not values """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( """ *3 passed* @@ -2791,8 +2841,8 @@ class TestFixtureMarker: ) result.stdout.no_fnmatch_line("*error*") - def test_fixture_finalizer(self, testdir): - testdir.makeconftest( + def test_fixture_finalizer(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest import sys @@ -2801,13 +2851,13 @@ class TestFixtureMarker: def browser(request): def finalize(): - sys.stdout.write('Finalized') + sys.stdout.write_text('Finalized') request.addfinalizer(finalize) return {} """ ) - b = testdir.mkdir("subdir") - b.join("test_overridden_fixture_finalizer.py").write( + b = pytester.mkdir("subdir") + b.joinpath("test_overridden_fixture_finalizer.py").write_text( textwrap.dedent( """\ import pytest @@ -2821,12 +2871,12 @@ class TestFixtureMarker: """ ) ) - reprec = testdir.runpytest("-s") + reprec = pytester.runpytest("-s") for test in ["test_browser"]: reprec.stdout.fnmatch_lines(["*Finalized*"]) - def test_class_scope_with_normal_tests(self, testdir): - testpath = testdir.makepyfile( + def test_class_scope_with_normal_tests(self, pytester: Pytester) -> None: + testpath = pytester.makepyfile( """ import pytest @@ -2849,12 +2899,12 @@ class TestFixtureMarker: def test_c(self, a): assert a == 3""" ) - reprec = testdir.inline_run(testpath) + reprec = pytester.inline_run(testpath) for test in ["test_a", "test_b", "test_c"]: assert reprec.matchreport(test).passed - def test_request_is_clean(self, testdir): - testdir.makepyfile( + def test_request_is_clean(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest values = [] @@ -2865,12 +2915,12 @@ class TestFixtureMarker: pass """ ) - reprec = testdir.inline_run("-s") + reprec = pytester.inline_run("-s") values = reprec.getcalls("pytest_runtest_call")[0].item.module.values assert values == [1, 2] - def test_parametrize_separated_lifecycle(self, testdir): - testdir.makepyfile( + def test_parametrize_separated_lifecycle(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -2886,7 +2936,7 @@ class TestFixtureMarker: values.append(arg) """ ) - reprec = testdir.inline_run("-vs") + reprec = pytester.inline_run("-vs") reprec.assertoutcome(passed=4) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values import pprint @@ -2898,8 +2948,10 @@ class TestFixtureMarker: assert values[3] == values[4] == 2 assert values[5] == "fin2" - def test_parametrize_function_scoped_finalizers_called(self, testdir): - testdir.makepyfile( + def test_parametrize_function_scoped_finalizers_called( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest @@ -2919,13 +2971,15 @@ class TestFixtureMarker: assert values == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"] """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=5) @pytest.mark.parametrize("scope", ["session", "function", "module"]) - def test_finalizer_order_on_parametrization(self, scope, testdir): + def test_finalizer_order_on_parametrization( + self, scope, pytester: Pytester + ) -> None: """#246""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest values = [] @@ -2956,12 +3010,12 @@ class TestFixtureMarker: """ % {"scope": scope} ) - reprec = testdir.inline_run("-lvs") + reprec = pytester.inline_run("-lvs") reprec.assertoutcome(passed=3) - def test_class_scope_parametrization_ordering(self, testdir): + def test_class_scope_parametrization_ordering(self, pytester: Pytester) -> None: """#396""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest values = [] @@ -2982,7 +3036,7 @@ class TestFixtureMarker: values.append("test_population") """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=6) values = reprec.getcalls("pytest_runtest_call")[0].item.module.values assert values == [ @@ -2998,8 +3052,8 @@ class TestFixtureMarker: "fin Doe", ] - def test_parametrize_setup_function(self, testdir): - testdir.makepyfile( + def test_parametrize_setup_function(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -3028,11 +3082,13 @@ class TestFixtureMarker: """ ) - reprec = testdir.inline_run("-v") + reprec = pytester.inline_run("-v") reprec.assertoutcome(passed=6) - def test_fixture_marked_function_not_collected_as_test(self, testdir): - testdir.makepyfile( + def test_fixture_marked_function_not_collected_as_test( + self, pytester: Pytester + ) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture @@ -3043,11 +3099,11 @@ class TestFixtureMarker: assert test_app == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_params_and_ids(self, testdir): - testdir.makepyfile( + def test_params_and_ids(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -3060,11 +3116,11 @@ class TestFixtureMarker: assert 1 """ ) - res = testdir.runpytest("-v") + res = pytester.runpytest("-v") res.stdout.fnmatch_lines(["*test_foo*alpha*", "*test_foo*beta*"]) - def test_params_and_ids_yieldfixture(self, testdir): - testdir.makepyfile( + def test_params_and_ids_yieldfixture(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -3076,12 +3132,14 @@ class TestFixtureMarker: assert 1 """ ) - res = testdir.runpytest("-v") + res = pytester.runpytest("-v") res.stdout.fnmatch_lines(["*test_foo*alpha*", "*test_foo*beta*"]) - def test_deterministic_fixture_collection(self, testdir, monkeypatch): + def test_deterministic_fixture_collection( + self, pytester: Pytester, monkeypatch + ) -> None: """#920""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -3106,21 +3164,21 @@ class TestFixtureMarker: """ ) monkeypatch.setenv("PYTHONHASHSEED", "1") - out1 = testdir.runpytest_subprocess("-v") + out1 = pytester.runpytest_subprocess("-v") monkeypatch.setenv("PYTHONHASHSEED", "2") - out2 = testdir.runpytest_subprocess("-v") - out1 = [ + out2 = pytester.runpytest_subprocess("-v") + output1 = [ line for line in out1.outlines if line.startswith("test_deterministic_fixture_collection.py::test_foo") ] - out2 = [ + output2 = [ line for line in out2.outlines if line.startswith("test_deterministic_fixture_collection.py::test_foo") ] - assert len(out1) == 12 - assert out1 == out2 + assert len(output1) == 12 + assert output1 == output2 class TestRequestScopeAccess: @@ -3134,8 +3192,8 @@ class TestRequestScopeAccess: ], ) - def test_setup(self, testdir, scope, ok, error): - testdir.makepyfile( + def test_setup(self, pytester: Pytester, scope, ok, error) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope=%r, autouse=True) @@ -3152,11 +3210,11 @@ class TestRequestScopeAccess: """ % (scope, ok.split(), error.split()) ) - reprec = testdir.inline_run("-l") + reprec = pytester.inline_run("-l") reprec.assertoutcome(passed=1) - def test_funcarg(self, testdir, scope, ok, error): - testdir.makepyfile( + def test_funcarg(self, pytester: Pytester, scope, ok, error) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope=%r) @@ -3173,13 +3231,13 @@ class TestRequestScopeAccess: """ % (scope, ok.split(), error.split()) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) class TestErrors: - def test_subfactory_missing_funcarg(self, testdir): - testdir.makepyfile( + def test_subfactory_missing_funcarg(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture() @@ -3189,14 +3247,14 @@ class TestErrors: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret != 0 result.stdout.fnmatch_lines( ["*def gen(qwe123):*", "*fixture*qwe123*not found*", "*1 error*"] ) - def test_issue498_fixture_finalizer_failing(self, testdir): - testdir.makepyfile( + def test_issue498_fixture_finalizer_failing(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture @@ -3215,7 +3273,7 @@ class TestErrors: assert values[0] != values[1] """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( """ *ERROR*teardown*test_1* @@ -3226,8 +3284,8 @@ class TestErrors: """ ) - def test_setupfunc_missing_funcarg(self, testdir): - testdir.makepyfile( + def test_setupfunc_missing_funcarg(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(autouse=True) @@ -3237,7 +3295,7 @@ class TestErrors: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret != 0 result.stdout.fnmatch_lines( ["*def gen(qwe123):*", "*fixture*qwe123*not found*", "*1 error*"] @@ -3245,12 +3303,12 @@ class TestErrors: class TestShowFixtures: - def test_funcarg_compat(self, testdir): - config = testdir.parseconfigure("--funcargs") + def test_funcarg_compat(self, pytester: Pytester) -> None: + config = pytester.parseconfigure("--funcargs") assert config.option.showfixtures - def test_show_fixtures(self, testdir): - result = testdir.runpytest("--fixtures") + def test_show_fixtures(self, pytester: Pytester) -> None: + result = pytester.runpytest("--fixtures") result.stdout.fnmatch_lines( [ "tmpdir_factory [[]session scope[]]", @@ -3260,8 +3318,8 @@ class TestShowFixtures: ] ) - def test_show_fixtures_verbose(self, testdir): - result = testdir.runpytest("--fixtures", "-v") + def test_show_fixtures_verbose(self, pytester: Pytester) -> None: + result = pytester.runpytest("--fixtures", "-v") result.stdout.fnmatch_lines( [ "tmpdir_factory [[]session scope[]] -- *tmpdir.py*", @@ -3271,8 +3329,8 @@ class TestShowFixtures: ] ) - def test_show_fixtures_testmodule(self, testdir): - p = testdir.makepyfile( + def test_show_fixtures_testmodule(self, pytester: Pytester) -> None: + p = pytester.makepyfile( ''' import pytest @pytest.fixture @@ -3283,7 +3341,7 @@ class TestShowFixtures: """ hello world """ ''' ) - result = testdir.runpytest("--fixtures", p) + result = pytester.runpytest("--fixtures", p) result.stdout.fnmatch_lines( """ *tmpdir @@ -3295,8 +3353,8 @@ class TestShowFixtures: result.stdout.no_fnmatch_line("*arg0*") @pytest.mark.parametrize("testmod", [True, False]) - def test_show_fixtures_conftest(self, testdir, testmod): - testdir.makeconftest( + def test_show_fixtures_conftest(self, pytester: Pytester, testmod) -> None: + pytester.makeconftest( ''' import pytest @pytest.fixture @@ -3305,13 +3363,13 @@ class TestShowFixtures: ''' ) if testmod: - testdir.makepyfile( + pytester.makepyfile( """ def test_hello(): pass """ ) - result = testdir.runpytest("--fixtures") + result = pytester.runpytest("--fixtures") result.stdout.fnmatch_lines( """ *tmpdir* @@ -3321,8 +3379,8 @@ class TestShowFixtures: """ ) - def test_show_fixtures_trimmed_doc(self, testdir): - p = testdir.makepyfile( + def test_show_fixtures_trimmed_doc(self, pytester: Pytester) -> None: + p = pytester.makepyfile( textwrap.dedent( '''\ import pytest @@ -3343,7 +3401,7 @@ class TestShowFixtures: ''' ) ) - result = testdir.runpytest("--fixtures", p) + result = pytester.runpytest("--fixtures", p) result.stdout.fnmatch_lines( textwrap.dedent( """\ @@ -3358,8 +3416,8 @@ class TestShowFixtures: ) ) - def test_show_fixtures_indented_doc(self, testdir): - p = testdir.makepyfile( + def test_show_fixtures_indented_doc(self, pytester: Pytester) -> None: + p = pytester.makepyfile( textwrap.dedent( '''\ import pytest @@ -3372,7 +3430,7 @@ class TestShowFixtures: ''' ) ) - result = testdir.runpytest("--fixtures", p) + result = pytester.runpytest("--fixtures", p) result.stdout.fnmatch_lines( textwrap.dedent( """\ @@ -3384,8 +3442,10 @@ class TestShowFixtures: ) ) - def test_show_fixtures_indented_doc_first_line_unindented(self, testdir): - p = testdir.makepyfile( + def test_show_fixtures_indented_doc_first_line_unindented( + self, pytester: Pytester + ) -> None: + p = pytester.makepyfile( textwrap.dedent( '''\ import pytest @@ -3398,7 +3458,7 @@ class TestShowFixtures: ''' ) ) - result = testdir.runpytest("--fixtures", p) + result = pytester.runpytest("--fixtures", p) result.stdout.fnmatch_lines( textwrap.dedent( """\ @@ -3411,8 +3471,8 @@ class TestShowFixtures: ) ) - def test_show_fixtures_indented_in_class(self, testdir): - p = testdir.makepyfile( + def test_show_fixtures_indented_in_class(self, pytester: Pytester) -> None: + p = pytester.makepyfile( textwrap.dedent( '''\ import pytest @@ -3426,7 +3486,7 @@ class TestShowFixtures: ''' ) ) - result = testdir.runpytest("--fixtures", p) + result = pytester.runpytest("--fixtures", p) result.stdout.fnmatch_lines( textwrap.dedent( """\ @@ -3439,9 +3499,9 @@ class TestShowFixtures: ) ) - def test_show_fixtures_different_files(self, testdir): + def test_show_fixtures_different_files(self, pytester: Pytester) -> None: """`--fixtures` only shows fixtures from first file (#833).""" - testdir.makepyfile( + pytester.makepyfile( test_a=''' import pytest @@ -3454,7 +3514,7 @@ class TestShowFixtures: pass ''' ) - testdir.makepyfile( + pytester.makepyfile( test_b=''' import pytest @@ -3467,7 +3527,7 @@ class TestShowFixtures: pass ''' ) - result = testdir.runpytest("--fixtures") + result = pytester.runpytest("--fixtures") result.stdout.fnmatch_lines( """ * fixtures defined from test_a * @@ -3480,8 +3540,8 @@ class TestShowFixtures: """ ) - def test_show_fixtures_with_same_name(self, testdir): - testdir.makeconftest( + def test_show_fixtures_with_same_name(self, pytester: Pytester) -> None: + pytester.makeconftest( ''' import pytest @pytest.fixture @@ -3490,13 +3550,13 @@ class TestShowFixtures: return "Hello World" ''' ) - testdir.makepyfile( + pytester.makepyfile( """ def test_foo(arg1): assert arg1 == "Hello World" """ ) - testdir.makepyfile( + pytester.makepyfile( ''' import pytest @pytest.fixture @@ -3507,7 +3567,7 @@ class TestShowFixtures: assert arg1 == "Hi" ''' ) - result = testdir.runpytest("--fixtures") + result = pytester.runpytest("--fixtures") result.stdout.fnmatch_lines( """ * fixtures defined from conftest * @@ -3531,8 +3591,8 @@ class TestShowFixtures: class TestContextManagerFixtureFuncs: - def test_simple(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_simple(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture @@ -3547,7 +3607,7 @@ class TestContextManagerFixtureFuncs: assert 0 """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *setup* @@ -3559,8 +3619,8 @@ class TestContextManagerFixtureFuncs: """ ) - def test_scoped(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_scoped(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="module") @@ -3574,7 +3634,7 @@ class TestContextManagerFixtureFuncs: print("test2", arg1) """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *setup* @@ -3584,8 +3644,8 @@ class TestContextManagerFixtureFuncs: """ ) - def test_setup_exception(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_setup_exception(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="module") @@ -3596,7 +3656,7 @@ class TestContextManagerFixtureFuncs: pass """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *pytest.fail*setup* @@ -3604,8 +3664,8 @@ class TestContextManagerFixtureFuncs: """ ) - def test_teardown_exception(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_teardown_exception(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="module") @@ -3616,7 +3676,7 @@ class TestContextManagerFixtureFuncs: pass """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *pytest.fail*teardown* @@ -3624,8 +3684,8 @@ class TestContextManagerFixtureFuncs: """ ) - def test_yields_more_than_one(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_yields_more_than_one(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(scope="module") @@ -3636,7 +3696,7 @@ class TestContextManagerFixtureFuncs: pass """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *fixture function* @@ -3644,8 +3704,8 @@ class TestContextManagerFixtureFuncs: """ ) - def test_custom_name(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_custom_name(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(name='meow') @@ -3655,13 +3715,13 @@ class TestContextManagerFixtureFuncs: print(meow) """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines(["*mew*"]) class TestParameterizedSubRequest: - def test_call_from_fixture(self, testdir): - testdir.makepyfile( + def test_call_from_fixture(self, pytester: Pytester) -> None: + pytester.makepyfile( test_call_from_fixture=""" import pytest @@ -3677,7 +3737,7 @@ class TestParameterizedSubRequest: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "The requested fixture has no parameter defined for test:", @@ -3690,8 +3750,8 @@ class TestParameterizedSubRequest: ] ) - def test_call_from_test(self, testdir): - testdir.makepyfile( + def test_call_from_test(self, pytester: Pytester) -> None: + pytester.makepyfile( test_call_from_test=""" import pytest @@ -3703,7 +3763,7 @@ class TestParameterizedSubRequest: request.getfixturevalue('fix_with_param') """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "The requested fixture has no parameter defined for test:", @@ -3716,8 +3776,8 @@ class TestParameterizedSubRequest: ] ) - def test_external_fixture(self, testdir): - testdir.makeconftest( + def test_external_fixture(self, pytester: Pytester) -> None: + pytester.makeconftest( """ import pytest @@ -3727,13 +3787,13 @@ class TestParameterizedSubRequest: """ ) - testdir.makepyfile( + pytester.makepyfile( test_external_fixture=""" def test_foo(request): request.getfixturevalue('fix_with_param') """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "The requested fixture has no parameter defined for test:", @@ -3747,11 +3807,11 @@ class TestParameterizedSubRequest: ] ) - def test_non_relative_path(self, testdir): - tests_dir = testdir.mkdir("tests") - fixdir = testdir.mkdir("fixtures") - fixfile = fixdir.join("fix.py") - fixfile.write( + def test_non_relative_path(self, pytester: Pytester) -> None: + tests_dir = pytester.mkdir("tests") + fixdir = pytester.mkdir("fixtures") + fixfile = fixdir.joinpath("fix.py") + fixfile.write_text( textwrap.dedent( """\ import pytest @@ -3763,8 +3823,8 @@ class TestParameterizedSubRequest: ) ) - testfile = tests_dir.join("test_foos.py") - testfile.write( + testfile = tests_dir.joinpath("test_foos.py") + testfile.write_text( textwrap.dedent( """\ from fix import fix_with_param @@ -3775,9 +3835,9 @@ class TestParameterizedSubRequest: ) ) - tests_dir.chdir() - testdir.syspathinsert(fixdir) - result = testdir.runpytest() + os.chdir(tests_dir) + pytester.syspathinsert(fixdir) + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "The requested fixture has no parameter defined for test:", @@ -3792,9 +3852,9 @@ class TestParameterizedSubRequest: ) # With non-overlapping rootdir, passing tests_dir. - rootdir = testdir.mkdir("rootdir") - rootdir.chdir() - result = testdir.runpytest("--rootdir", rootdir, tests_dir) + rootdir = pytester.mkdir("rootdir") + os.chdir(rootdir) + result = pytester.runpytest("--rootdir", rootdir, tests_dir) result.stdout.fnmatch_lines( [ "The requested fixture has no parameter defined for test:", @@ -3809,8 +3869,8 @@ class TestParameterizedSubRequest: ) -def test_pytest_fixture_setup_and_post_finalizer_hook(testdir): - testdir.makeconftest( +def test_pytest_fixture_setup_and_post_finalizer_hook(pytester: Pytester) -> None: + pytester.makeconftest( """ def pytest_fixture_setup(fixturedef, request): print('ROOT setup hook called for {0} from {1}'.format(fixturedef.argname, request.node.name)) @@ -3818,7 +3878,7 @@ def test_pytest_fixture_setup_and_post_finalizer_hook(testdir): print('ROOT finalizer hook called for {0} from {1}'.format(fixturedef.argname, request.node.name)) """ ) - testdir.makepyfile( + pytester.makepyfile( **{ "tests/conftest.py": """ def pytest_fixture_setup(fixturedef, request): @@ -3839,7 +3899,7 @@ def test_pytest_fixture_setup_and_post_finalizer_hook(testdir): """, } ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") assert result.ret == 0 result.stdout.fnmatch_lines( [ @@ -3856,10 +3916,12 @@ class TestScopeOrdering: """Class of tests that ensure fixtures are ordered based on their scopes (#2405)""" @pytest.mark.parametrize("variant", ["mark", "autouse"]) - def test_func_closure_module_auto(self, testdir, variant, monkeypatch): + def test_func_closure_module_auto( + self, pytester: Pytester, variant, monkeypatch + ) -> None: """Semantically identical to the example posted in #2405 when ``use_mark=True``""" monkeypatch.setenv("FIXTURE_ACTIVATION_VARIANT", variant) - testdir.makepyfile( + pytester.makepyfile( """ import warnings import os @@ -3885,16 +3947,18 @@ class TestScopeOrdering: pass """ ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) assert request.fixturenames == "m1 f1".split() - def test_func_closure_with_native_fixtures(self, testdir, monkeypatch) -> None: + def test_func_closure_with_native_fixtures( + self, pytester: Pytester, monkeypatch: MonkeyPatch + ) -> None: """Sanity check that verifies the order returned by the closures and the actual fixture execution order: The execution order may differ because of fixture inter-dependencies. """ monkeypatch.setattr(pytest, "FIXTURE_ORDER", [], raising=False) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -3931,19 +3995,19 @@ class TestScopeOrdering: def test_foo(f1, p1, m1, f2, s1): pass """ ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) # order of fixtures based on their scope and position in the parameter list assert ( request.fixturenames == "s1 my_tmpdir_factory p1 m1 f1 f2 my_tmpdir".split() ) - testdir.runpytest() + pytester.runpytest() # actual fixture execution differs: dependent fixtures must be created first ("my_tmpdir") FIXTURE_ORDER = pytest.FIXTURE_ORDER # type: ignore[attr-defined] assert FIXTURE_ORDER == "s1 my_tmpdir_factory p1 m1 my_tmpdir f1 f2".split() - def test_func_closure_module(self, testdir): - testdir.makepyfile( + def test_func_closure_module(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -3957,15 +4021,15 @@ class TestScopeOrdering: pass """ ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) assert request.fixturenames == "m1 f1".split() - def test_func_closure_scopes_reordered(self, testdir): + def test_func_closure_scopes_reordered(self, pytester: Pytester) -> None: """Test ensures that fixtures are ordered by scope regardless of the order of the parameters, although fixtures of same scope keep the declared order """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -3990,13 +4054,15 @@ class TestScopeOrdering: pass """ ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) assert request.fixturenames == "s1 m1 c1 f2 f1".split() - def test_func_closure_same_scope_closer_root_first(self, testdir): + def test_func_closure_same_scope_closer_root_first( + self, pytester: Pytester + ) -> None: """Auto-use fixtures of same scope are ordered by closer-to-root first""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -4004,7 +4070,7 @@ class TestScopeOrdering: def m_conf(): pass """ ) - testdir.makepyfile( + pytester.makepyfile( **{ "sub/conftest.py": """ import pytest @@ -4030,13 +4096,13 @@ class TestScopeOrdering: """, } ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) assert request.fixturenames == "p_sub m_conf m_sub m_test f1".split() - def test_func_closure_all_scopes_complex(self, testdir): + def test_func_closure_all_scopes_complex(self, pytester: Pytester) -> None: """Complex test involving all scopes and mixing autouse with normal fixtures""" - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -4047,8 +4113,8 @@ class TestScopeOrdering: def p1(): pass """ ) - testdir.makepyfile(**{"__init__.py": ""}) - testdir.makepyfile( + pytester.makepyfile(**{"__init__.py": ""}) + pytester.makepyfile( """ import pytest @@ -4074,11 +4140,11 @@ class TestScopeOrdering: pass """ ) - items, _ = testdir.inline_genitems() + items, _ = pytester.inline_genitems() request = FixtureRequest(items[0], _ispytest=True) assert request.fixturenames == "s1 p1 m1 m2 c1 f2 f1".split() - def test_multiple_packages(self, testdir): + def test_multiple_packages(self, pytester: Pytester) -> None: """Complex test involving multiple package fixtures. Make sure teardowns are executed in order. . @@ -4093,11 +4159,12 @@ class TestScopeOrdering: ├── conftest.py └── test_2.py """ - root = testdir.mkdir("root") - root.join("__init__.py").write("values = []") - sub1 = root.mkdir("sub1") - sub1.ensure("__init__.py") - sub1.join("conftest.py").write( + root = pytester.mkdir("root") + root.joinpath("__init__.py").write_text("values = []") + sub1 = root.joinpath("sub1") + sub1.mkdir() + sub1.joinpath("__init__.py").touch() + sub1.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -4110,7 +4177,7 @@ class TestScopeOrdering: """ ) ) - sub1.join("test_1.py").write( + sub1.joinpath("test_1.py").write_text( textwrap.dedent( """\ from .. import values @@ -4119,9 +4186,10 @@ class TestScopeOrdering: """ ) ) - sub2 = root.mkdir("sub2") - sub2.ensure("__init__.py") - sub2.join("conftest.py").write( + sub2 = root.joinpath("sub2") + sub2.mkdir() + sub2.joinpath("__init__.py").touch() + sub2.joinpath("conftest.py").write_text( textwrap.dedent( """\ import pytest @@ -4134,7 +4202,7 @@ class TestScopeOrdering: """ ) ) - sub2.join("test_2.py").write( + sub2.joinpath("test_2.py").write_text( textwrap.dedent( """\ from .. import values @@ -4143,14 +4211,14 @@ class TestScopeOrdering: """ ) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_class_fixture_self_instance(self, testdir): + def test_class_fixture_self_instance(self, pytester: Pytester) -> None: """Check that plugin classes which implement fixtures receive the plugin instance as self (see #2270). """ - testdir.makeconftest( + pytester.makeconftest( """ import pytest @@ -4168,14 +4236,14 @@ class TestScopeOrdering: """ ) - testdir.makepyfile( + pytester.makepyfile( """ class TestClass(object): def test_1(self, myfix): assert myfix == 1 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) @@ -4190,9 +4258,9 @@ def test_call_fixture_function_error(): assert fix() == 1 -def test_fixture_param_shadowing(testdir): +def test_fixture_param_shadowing(pytester: Pytester) -> None: """Parametrized arguments would be shadowed if a fixture with the same name also exists (#5036)""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -4225,7 +4293,7 @@ def test_fixture_param_shadowing(testdir): """ ) # Only one test should have run - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.assert_outcomes(passed=4) result.stdout.fnmatch_lines(["*::test_direct[[]1[]]*"]) result.stdout.fnmatch_lines(["*::test_normal_fixture[[]a[]]*"]) @@ -4233,9 +4301,9 @@ def test_fixture_param_shadowing(testdir): result.stdout.fnmatch_lines(["*::test_indirect[[]1[]]*"]) -def test_fixture_named_request(testdir): - testdir.copy_example("fixtures/test_fixture_named_request.py") - result = testdir.runpytest() +def test_fixture_named_request(pytester: Pytester) -> None: + pytester.copy_example("fixtures/test_fixture_named_request.py") + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*'request' is a reserved word for fixtures, use another name:", @@ -4244,9 +4312,9 @@ def test_fixture_named_request(testdir): ) -def test_indirect_fixture_does_not_break_scope(testdir): +def test_indirect_fixture_does_not_break_scope(pytester: Pytester) -> None: """Ensure that fixture scope is respected when using indirect fixtures (#570)""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest instantiated = [] @@ -4291,14 +4359,14 @@ def test_indirect_fixture_does_not_break_scope(testdir): ] """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.assert_outcomes(passed=7) -def test_fixture_parametrization_nparray(testdir): +def test_fixture_parametrization_nparray(pytester: Pytester) -> None: pytest.importorskip("numpy") - testdir.makepyfile( + pytester.makepyfile( """ from numpy import linspace from pytest import fixture @@ -4311,18 +4379,18 @@ def test_fixture_parametrization_nparray(testdir): assert value == value """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.assert_outcomes(passed=10) -def test_fixture_arg_ordering(testdir): +def test_fixture_arg_ordering(pytester: Pytester) -> None: """ This test describes how fixtures in the same scope but without explicit dependencies between them are created. While users should make dependencies explicit, often they rely on this order, so this test exists to catch regressions in this regard. See #6540 and #6492. """ - p1 = testdir.makepyfile( + p1 = pytester.makepyfile( """ import pytest @@ -4346,12 +4414,12 @@ def test_fixture_arg_ordering(testdir): assert suffixes == ["fix_1", "fix_2", "fix_3", "fix_4", "fix_5"] """ ) - result = testdir.runpytest("-vv", str(p1)) + result = pytester.runpytest("-vv", str(p1)) assert result.ret == 0 -def test_yield_fixture_with_no_value(testdir): - testdir.makepyfile( +def test_yield_fixture_with_no_value(pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.fixture(name='custom') @@ -4364,7 +4432,7 @@ def test_yield_fixture_with_no_value(testdir): """ ) expected = "E ValueError: custom did not yield a value" - result = testdir.runpytest() + result = pytester.runpytest() result.assert_outcomes(errors=1) result.stdout.fnmatch_lines([expected]) assert result.ret == ExitCode.TESTS_FAILED diff --git a/testing/python/integration.py b/testing/python/integration.py index f006e5ed4..5dce6bdca 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -3,13 +3,14 @@ from typing import Any import pytest from _pytest import runner from _pytest._code import getfslineno +from _pytest.pytester import Pytester class TestOEJSKITSpecials: def test_funcarg_non_pycollectobj( - self, testdir, recwarn + self, pytester: Pytester, recwarn ) -> None: # rough jstests usage - testdir.makeconftest( + pytester.makeconftest( """ import pytest def pytest_pycollect_makeitem(collector, name, obj): @@ -20,7 +21,7 @@ class TestOEJSKITSpecials: return self.fspath, 3, "xyz" """ ) - modcol = testdir.getmodulecol( + modcol = pytester.getmodulecol( """ import pytest @pytest.fixture @@ -39,8 +40,10 @@ class TestOEJSKITSpecials: pytest._fillfuncargs(clscol) assert clscol.funcargs["arg1"] == 42 - def test_autouse_fixture(self, testdir, recwarn) -> None: # rough jstests usage - testdir.makeconftest( + def test_autouse_fixture( + self, pytester: Pytester, recwarn + ) -> None: # rough jstests usage + pytester.makeconftest( """ import pytest def pytest_pycollect_makeitem(collector, name, obj): @@ -51,7 +54,7 @@ class TestOEJSKITSpecials: return self.fspath, 3, "xyz" """ ) - modcol = testdir.getmodulecol( + modcol = pytester.getmodulecol( """ import pytest @pytest.fixture(autouse=True) @@ -125,8 +128,8 @@ class TestMockDecoration: values = getfuncargnames(f) assert values == ("y", "z") - def test_unittest_mock(self, testdir): - testdir.makepyfile( + def test_unittest_mock(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import unittest.mock class T(unittest.TestCase): @@ -137,11 +140,11 @@ class TestMockDecoration: abspath.assert_any_call("hello") """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_unittest_mock_and_fixture(self, testdir): - testdir.makepyfile( + def test_unittest_mock_and_fixture(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import os.path import unittest.mock @@ -158,12 +161,12 @@ class TestMockDecoration: os.path.abspath("hello") """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_unittest_mock_and_pypi_mock(self, testdir): + def test_unittest_mock_and_pypi_mock(self, pytester: Pytester) -> None: pytest.importorskip("mock", "1.0.1") - testdir.makepyfile( + pytester.makepyfile( """ import mock import unittest.mock @@ -181,15 +184,15 @@ class TestMockDecoration: abspath.assert_any_call("hello") """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_mock_sentinel_check_against_numpy_like(self, testdir): + def test_mock_sentinel_check_against_numpy_like(self, pytester: Pytester) -> None: """Ensure our function that detects mock arguments compares against sentinels using identity to circumvent objects which can't be compared with equality against others in a truth context, like with numpy arrays (#5606). """ - testdir.makepyfile( + pytester.makepyfile( dummy=""" class NumpyLike: def __init__(self, value): @@ -199,7 +202,7 @@ class TestMockDecoration: FOO = NumpyLike(10) """ ) - testdir.makepyfile( + pytester.makepyfile( """ from unittest.mock import patch import dummy @@ -209,12 +212,12 @@ class TestMockDecoration: assert dummy.FOO.value == 50 """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) - def test_mock(self, testdir): + def test_mock(self, pytester: Pytester) -> None: pytest.importorskip("mock", "1.0.1") - testdir.makepyfile( + pytester.makepyfile( """ import os import unittest @@ -237,7 +240,7 @@ class TestMockDecoration: assert os.path.basename("123") == "mock_basename" """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) calls = reprec.getcalls("pytest_runtest_logreport") funcnames = [ @@ -245,9 +248,9 @@ class TestMockDecoration: ] assert funcnames == ["T.test_hello", "test_someting"] - def test_mock_sorting(self, testdir): + def test_mock_sorting(self, pytester: Pytester) -> None: pytest.importorskip("mock", "1.0.1") - testdir.makepyfile( + pytester.makepyfile( """ import os import mock @@ -263,15 +266,15 @@ class TestMockDecoration: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() calls = reprec.getreports("pytest_runtest_logreport") calls = [x for x in calls if x.when == "call"] names = [x.nodeid.split("::")[-1] for x in calls] assert names == ["test_one", "test_two", "test_three"] - def test_mock_double_patch_issue473(self, testdir): + def test_mock_double_patch_issue473(self, pytester: Pytester) -> None: pytest.importorskip("mock", "1.0.1") - testdir.makepyfile( + pytester.makepyfile( """ from mock import patch from pytest import mark @@ -284,13 +287,13 @@ class TestMockDecoration: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=1) class TestReRunTests: - def test_rerun(self, testdir): - testdir.makeconftest( + def test_rerun(self, pytester: Pytester) -> None: + pytester.makeconftest( """ from _pytest.runner import runtestprotocol def pytest_runtest_protocol(item, nextitem): @@ -298,7 +301,7 @@ class TestReRunTests: runtestprotocol(item, log=True, nextitem=nextitem) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest count = 0 @@ -314,7 +317,7 @@ class TestReRunTests: pass """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") result.stdout.fnmatch_lines( """ *fix count 0* @@ -336,21 +339,21 @@ def test_pytestconfig_is_session_scoped() -> None: class TestNoselikeTestAttribute: - def test_module_with_global_test(self, testdir): - testdir.makepyfile( + def test_module_with_global_test(self, pytester: Pytester) -> None: + pytester.makepyfile( """ __test__ = False def test_hello(): pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() assert not reprec.getfailedcollections() calls = reprec.getreports("pytest_runtest_logreport") assert not calls - def test_class_and_method(self, testdir): - testdir.makepyfile( + def test_class_and_method(self, pytester: Pytester) -> None: + pytester.makepyfile( """ __test__ = True def test_func(): @@ -363,13 +366,13 @@ class TestNoselikeTestAttribute: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() assert not reprec.getfailedcollections() calls = reprec.getreports("pytest_runtest_logreport") assert not calls - def test_unittest_class(self, testdir): - testdir.makepyfile( + def test_unittest_class(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import unittest class TC(unittest.TestCase): @@ -381,20 +384,20 @@ class TestNoselikeTestAttribute: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() assert not reprec.getfailedcollections() call = reprec.getcalls("pytest_collection_modifyitems")[0] assert len(call.items) == 1 assert call.items[0].cls.__name__ == "TC" - def test_class_with_nasty_getattr(self, testdir): + def test_class_with_nasty_getattr(self, pytester: Pytester) -> None: """Make sure we handle classes with a custom nasty __getattr__ right. With a custom __getattr__ which e.g. returns a function (like with a RPC wrapper), we shouldn't assume this meant "__test__ = True". """ # https://github.com/pytest-dev/pytest/issues/1204 - testdir.makepyfile( + pytester.makepyfile( """ class MetaModel(type): @@ -413,7 +416,7 @@ class TestNoselikeTestAttribute: pass """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() assert not reprec.getfailedcollections() call = reprec.getcalls("pytest_collection_modifyitems")[0] assert not call.items @@ -422,8 +425,8 @@ class TestNoselikeTestAttribute: class TestParameterize: """#351""" - def test_idfn_marker(self, testdir): - testdir.makepyfile( + def test_idfn_marker(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -440,11 +443,11 @@ class TestParameterize: pass """ ) - res = testdir.runpytest("--collect-only") + res = pytester.runpytest("--collect-only") res.stdout.fnmatch_lines(["*spam-2*", "*ham-2*"]) - def test_idfn_fixture(self, testdir): - testdir.makepyfile( + def test_idfn_fixture(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -468,5 +471,5 @@ class TestParameterize: pass """ ) - res = testdir.runpytest("--collect-only") + res = pytester.runpytest("--collect-only") res.stdout.fnmatch_lines(["*spam-2*", "*ham-2*"]) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 676f1d988..c50ea53d2 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -23,7 +23,7 @@ from _pytest.compat import _format_args from _pytest.compat import getfuncargnames from _pytest.compat import NOTSET from _pytest.outcomes import fail -from _pytest.pytester import Testdir +from _pytest.pytester import Pytester from _pytest.python import _idval from _pytest.python import idmaker @@ -123,7 +123,7 @@ class TestMetafunc: ): metafunc.parametrize("x", [1], scope="doggy") # type: ignore[arg-type] - def test_parametrize_request_name(self, testdir: Testdir) -> None: + def test_parametrize_request_name(self, pytester: Pytester) -> None: """Show proper error when 'request' is used as a parameter name in parametrize (#6183)""" def func(request): @@ -550,12 +550,12 @@ class TestMetafunc: ) assert result == [expected] - def test_parametrize_ids_exception(self, testdir: Testdir) -> None: + def test_parametrize_ids_exception(self, pytester: Pytester) -> None: """ - :param testdir: the instance of Testdir class, a temporary + :param pytester: the instance of Pytester class, a temporary test directory. """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -567,7 +567,7 @@ class TestMetafunc: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "*Exception: bad ids", @@ -575,8 +575,8 @@ class TestMetafunc: ] ) - def test_parametrize_ids_returns_non_string(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_ids_returns_non_string(self, pytester: Pytester) -> None: + pytester.makepyfile( """\ import pytest @@ -592,7 +592,7 @@ class TestMetafunc: assert arg """ ) - result = testdir.runpytest("-vv", "-s") + result = pytester.runpytest("-vv", "-s") result.stdout.fnmatch_lines( [ "test_parametrize_ids_returns_non_string.py::test[arg0] PASSED", @@ -682,7 +682,7 @@ class TestMetafunc: ): metafunc.parametrize("x, y", [("a", "b")], indirect={}) # type: ignore[arg-type] - def test_parametrize_indirect_list_functional(self, testdir: Testdir) -> None: + def test_parametrize_indirect_list_functional(self, pytester: Pytester) -> None: """ #714 Test parametrization with 'indirect' parameter applied on @@ -690,10 +690,10 @@ class TestMetafunc: be used directly rather than being passed to the fixture y. - :param testdir: the instance of Testdir class, a temporary + :param pytester: the instance of Pytester class, a temporary test directory. """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope='function') @@ -708,7 +708,7 @@ class TestMetafunc: assert len(y) == 1 """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines(["*test_simple*a-b*", "*1 passed*"]) def test_parametrize_indirect_list_error(self) -> None: @@ -722,7 +722,7 @@ class TestMetafunc: metafunc.parametrize("x, y", [("a", "b")], indirect=["x", "z"]) def test_parametrize_uses_no_fixture_error_indirect_false( - self, testdir: Testdir + self, pytester: Pytester ) -> None: """The 'uses no fixture' error tells the user at collection time that the parametrize data they've set up doesn't correspond to the @@ -731,7 +731,7 @@ class TestMetafunc: #714 """ - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -740,14 +740,14 @@ class TestMetafunc: assert len(x) == 3 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*uses no argument 'y'*"]) def test_parametrize_uses_no_fixture_error_indirect_true( - self, testdir: Testdir + self, pytester: Pytester ) -> None: """#714""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope='function') @@ -762,14 +762,14 @@ class TestMetafunc: assert len(x) == 3 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*uses no fixture 'y'*"]) def test_parametrize_indirect_uses_no_fixture_error_indirect_string( - self, testdir: Testdir + self, pytester: Pytester ) -> None: """#714""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope='function') @@ -781,14 +781,14 @@ class TestMetafunc: assert len(x) == 3 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*uses no fixture 'y'*"]) def test_parametrize_indirect_uses_no_fixture_error_indirect_list( - self, testdir: Testdir + self, pytester: Pytester ) -> None: """#714""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope='function') @@ -800,12 +800,14 @@ class TestMetafunc: assert len(x) == 3 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*uses no fixture 'y'*"]) - def test_parametrize_argument_not_in_indirect_list(self, testdir: Testdir) -> None: + def test_parametrize_argument_not_in_indirect_list( + self, pytester: Pytester + ) -> None: """#714""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @pytest.fixture(scope='function') @@ -817,13 +819,13 @@ class TestMetafunc: assert len(x) == 3 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines(["*uses no argument 'y'*"]) def test_parametrize_gives_indicative_error_on_function_with_default_argument( - self, testdir + self, pytester: Pytester ) -> None: - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -832,13 +834,13 @@ class TestMetafunc: assert len(x) == 1 """ ) - result = testdir.runpytest("--collect-only") + result = pytester.runpytest("--collect-only") result.stdout.fnmatch_lines( ["*already takes an argument 'y' with a default value"] ) - def test_parametrize_functional(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_functional(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -853,7 +855,7 @@ class TestMetafunc: assert y == 2 """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( ["*test_simple*1-2*", "*test_simple*2-2*", "*2 passed*"] ) @@ -884,8 +886,8 @@ class TestMetafunc: assert metafunc._calls[1].funcargs == dict(x=3, y=4) assert metafunc._calls[1].id == "3-4" - def test_parametrize_multiple_times(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_multiple_times(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest pytestmark = pytest.mark.parametrize("x", [1,2]) @@ -897,12 +899,12 @@ class TestMetafunc: assert 0, x """ ) - result = testdir.runpytest() + result = pytester.runpytest() assert result.ret == 1 result.assert_outcomes(failed=6) - def test_parametrize_CSV(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_CSV(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @pytest.mark.parametrize("x, y,", [(1,2), (2,3)]) @@ -910,11 +912,11 @@ class TestMetafunc: assert x+1 == y """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) - def test_parametrize_class_scenarios(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_class_scenarios(self, pytester: Pytester) -> None: + pytester.makepyfile( """ # same as doc/en/example/parametrize scenario example def pytest_generate_tests(metafunc): @@ -941,7 +943,7 @@ class TestMetafunc: pass """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") assert result.ret == 0 result.stdout.fnmatch_lines( """ @@ -978,8 +980,8 @@ class TestMetafunc: class TestMetafuncFunctional: - def test_attributes(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_attributes(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ # assumes that generate/provide runs in the same process import sys, pytest @@ -1005,11 +1007,11 @@ class TestMetafuncFunctional: assert metafunc.cls == TestClass """ ) - result = testdir.runpytest(p, "-v") + result = pytester.runpytest(p, "-v") result.assert_outcomes(passed=2) - def test_two_functions(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_two_functions(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): metafunc.parametrize('arg1', [10, 20], ids=['0', '1']) @@ -1021,7 +1023,7 @@ class TestMetafuncFunctional: assert arg1 in (10, 20) """ ) - result = testdir.runpytest("-v", p) + result = pytester.runpytest("-v", p) result.stdout.fnmatch_lines( [ "*test_func1*0*PASS*", @@ -1032,8 +1034,8 @@ class TestMetafuncFunctional: ] ) - def test_noself_in_method(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_noself_in_method(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): assert 'xyz' not in metafunc.fixturenames @@ -1043,11 +1045,11 @@ class TestMetafuncFunctional: pass """ ) - result = testdir.runpytest(p) + result = pytester.runpytest(p) result.assert_outcomes(passed=1) - def test_generate_tests_in_class(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_generate_tests_in_class(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ class TestClass(object): def pytest_generate_tests(self, metafunc): @@ -1057,11 +1059,11 @@ class TestMetafuncFunctional: assert hello == "world" """ ) - result = testdir.runpytest("-v", p) + result = pytester.runpytest("-v", p) result.stdout.fnmatch_lines(["*test_myfunc*hello*PASS*", "*1 passed*"]) - def test_two_functions_not_same_instance(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_two_functions_not_same_instance(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): metafunc.parametrize('arg1', [10, 20], ids=["0", "1"]) @@ -1072,13 +1074,13 @@ class TestMetafuncFunctional: self.x = 1 """ ) - result = testdir.runpytest("-v", p) + result = pytester.runpytest("-v", p) result.stdout.fnmatch_lines( ["*test_func*0*PASS*", "*test_func*1*PASS*", "*2 pass*"] ) - def test_issue28_setup_method_in_generate_tests(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_issue28_setup_method_in_generate_tests(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): metafunc.parametrize('arg1', [1]) @@ -1090,11 +1092,11 @@ class TestMetafuncFunctional: self.val = 1 """ ) - result = testdir.runpytest(p) + result = pytester.runpytest(p) result.assert_outcomes(passed=1) - def test_parametrize_functional2(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_functional2(self, pytester: Pytester) -> None: + pytester.makepyfile( """ def pytest_generate_tests(metafunc): metafunc.parametrize("arg1", [1,2]) @@ -1103,13 +1105,13 @@ class TestMetafuncFunctional: assert 0, (arg1, arg2) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( ["*(1, 4)*", "*(1, 5)*", "*(2, 4)*", "*(2, 5)*", "*4 failed*"] ) - def test_parametrize_and_inner_getfixturevalue(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_parametrize_and_inner_getfixturevalue(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): metafunc.parametrize("arg1", [1], indirect=True) @@ -1129,11 +1131,11 @@ class TestMetafuncFunctional: assert arg1 == 11 """ ) - result = testdir.runpytest("-v", p) + result = pytester.runpytest("-v", p) result.stdout.fnmatch_lines(["*test_func1*1*PASS*", "*1 passed*"]) - def test_parametrize_on_setup_arg(self, testdir: Testdir) -> None: - p = testdir.makepyfile( + def test_parametrize_on_setup_arg(self, pytester: Pytester) -> None: + p = pytester.makepyfile( """ def pytest_generate_tests(metafunc): assert "arg1" in metafunc.fixturenames @@ -1152,17 +1154,17 @@ class TestMetafuncFunctional: assert arg2 == 10 """ ) - result = testdir.runpytest("-v", p) + result = pytester.runpytest("-v", p) result.stdout.fnmatch_lines(["*test_func*1*PASS*", "*1 passed*"]) - def test_parametrize_with_ids(self, testdir: Testdir) -> None: - testdir.makeini( + def test_parametrize_with_ids(self, pytester: Pytester) -> None: + pytester.makeini( """ [pytest] console_output_style=classic """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -1173,14 +1175,14 @@ class TestMetafuncFunctional: assert a == b """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") assert result.ret == 1 result.stdout.fnmatch_lines_random( ["*test_function*basic*PASSED", "*test_function*advanced*FAILED"] ) - def test_parametrize_without_ids(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_without_ids(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -1191,7 +1193,7 @@ class TestMetafuncFunctional: assert 1 """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( """ *test_function*1-b0* @@ -1199,8 +1201,8 @@ class TestMetafuncFunctional: """ ) - def test_parametrize_with_None_in_ids(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_with_None_in_ids(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -1211,7 +1213,7 @@ class TestMetafuncFunctional: assert a == b """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") assert result.ret == 1 result.stdout.fnmatch_lines_random( [ @@ -1221,9 +1223,9 @@ class TestMetafuncFunctional: ] ) - def test_fixture_parametrized_empty_ids(self, testdir: Testdir) -> None: + def test_fixture_parametrized_empty_ids(self, pytester: Pytester) -> None: """Fixtures parametrized with empty ids cause an internal error (#1849).""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1235,12 +1237,12 @@ class TestMetafuncFunctional: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 1 skipped *"]) - def test_parametrized_empty_ids(self, testdir: Testdir) -> None: + def test_parametrized_empty_ids(self, pytester: Pytester) -> None: """Tests parametrized with empty ids cause an internal error (#1849).""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1249,12 +1251,12 @@ class TestMetafuncFunctional: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 1 skipped *"]) - def test_parametrized_ids_invalid_type(self, testdir: Testdir) -> None: + def test_parametrized_ids_invalid_type(self, pytester: Pytester) -> None: """Test error with non-strings/non-ints, without generator (#1857).""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1263,7 +1265,7 @@ class TestMetafuncFunctional: assert x * 2 == expected """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines( [ "In test_ids_numbers: ids must be list of string/float/int/bool," @@ -1272,9 +1274,9 @@ class TestMetafuncFunctional: ) def test_parametrize_with_identical_ids_get_unique_names( - self, testdir: Testdir + self, pytester: Pytester ) -> None: - testdir.makepyfile( + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -1285,7 +1287,7 @@ class TestMetafuncFunctional: assert a == b """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") assert result.ret == 1 result.stdout.fnmatch_lines_random( ["*test_function*a0*PASSED*", "*test_function*a1*FAILED*"] @@ -1293,9 +1295,9 @@ class TestMetafuncFunctional: @pytest.mark.parametrize(("scope", "length"), [("module", 2), ("function", 4)]) def test_parametrize_scope_overrides( - self, testdir: Testdir, scope: str, length: int + self, pytester: Pytester, scope: str, length: int ) -> None: - testdir.makepyfile( + pytester.makepyfile( """ import pytest values = [] @@ -1316,11 +1318,11 @@ class TestMetafuncFunctional: """ % (scope, length) ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=5) - def test_parametrize_issue323(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_issue323(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1334,11 +1336,11 @@ class TestMetafuncFunctional: pass """ ) - reprec = testdir.inline_run("--collect-only") + reprec = pytester.inline_run("--collect-only") assert not reprec.getcalls("pytest_internalerror") - def test_usefixtures_seen_in_generate_tests(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_usefixtures_seen_in_generate_tests(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest def pytest_generate_tests(metafunc): @@ -1350,13 +1352,13 @@ class TestMetafuncFunctional: pass """ ) - reprec = testdir.runpytest() + reprec = pytester.runpytest() reprec.assert_outcomes(passed=1) - def test_generate_tests_only_done_in_subdir(self, testdir: Testdir) -> None: - sub1 = testdir.mkpydir("sub1") - sub2 = testdir.mkpydir("sub2") - sub1.join("conftest.py").write( + def test_generate_tests_only_done_in_subdir(self, pytester: Pytester) -> None: + sub1 = pytester.mkpydir("sub1") + sub2 = pytester.mkpydir("sub2") + sub1.joinpath("conftest.py").write_text( textwrap.dedent( """\ def pytest_generate_tests(metafunc): @@ -1364,7 +1366,7 @@ class TestMetafuncFunctional: """ ) ) - sub2.join("conftest.py").write( + sub2.joinpath("conftest.py").write_text( textwrap.dedent( """\ def pytest_generate_tests(metafunc): @@ -1372,13 +1374,13 @@ class TestMetafuncFunctional: """ ) ) - sub1.join("test_in_sub1.py").write("def test_1(): pass") - sub2.join("test_in_sub2.py").write("def test_2(): pass") - result = testdir.runpytest("--keep-duplicates", "-v", "-s", sub1, sub2, sub1) + sub1.joinpath("test_in_sub1.py").write_text("def test_1(): pass") + sub2.joinpath("test_in_sub2.py").write_text("def test_2(): pass") + result = pytester.runpytest("--keep-duplicates", "-v", "-s", sub1, sub2, sub1) result.assert_outcomes(passed=3) - def test_generate_same_function_names_issue403(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_generate_same_function_names_issue403(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1392,12 +1394,12 @@ class TestMetafuncFunctional: test_y = make_tests() """ ) - reprec = testdir.runpytest() + reprec = pytester.runpytest() reprec.assert_outcomes(passed=4) - def test_parametrize_misspelling(self, testdir: Testdir) -> None: + def test_parametrize_misspelling(self, pytester: Pytester) -> None: """#463""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1406,7 +1408,7 @@ class TestMetafuncFunctional: pass """ ) - result = testdir.runpytest("--collectonly") + result = pytester.runpytest("--collectonly") result.stdout.fnmatch_lines( [ "collected 0 items / 1 error", @@ -1426,8 +1428,8 @@ class TestMetafuncFunctionalAuto: """Tests related to automatically find out the correct scope for parametrized tests (#1832).""" - def test_parametrize_auto_scope(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_auto_scope(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1445,11 +1447,11 @@ class TestMetafuncFunctionalAuto: """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 3 passed *"]) - def test_parametrize_auto_scope_indirect(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_auto_scope_indirect(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1468,11 +1470,11 @@ class TestMetafuncFunctionalAuto: assert echo in (1, 2, 3) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 3 passed *"]) - def test_parametrize_auto_scope_override_fixture(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_auto_scope_override_fixture(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1485,11 +1487,11 @@ class TestMetafuncFunctionalAuto: assert animal in ('dog', 'cat') """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 2 passed *"]) - def test_parametrize_all_indirects(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_all_indirects(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1512,11 +1514,11 @@ class TestMetafuncFunctionalAuto: assert echo in (1, 2, 3) """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["* 3 passed *"]) def test_parametrize_some_arguments_auto_scope( - self, testdir: Testdir, monkeypatch + self, pytester: Pytester, monkeypatch ) -> None: """Integration test for (#3941)""" class_fix_setup: List[object] = [] @@ -1524,7 +1526,7 @@ class TestMetafuncFunctionalAuto: func_fix_setup: List[object] = [] monkeypatch.setattr(sys, "func_fix_setup", func_fix_setup, raising=False) - testdir.makepyfile( + pytester.makepyfile( """ import pytest import sys @@ -1545,13 +1547,13 @@ class TestMetafuncFunctionalAuto: pass """ ) - result = testdir.runpytest_inprocess() + result = pytester.runpytest_inprocess() result.stdout.fnmatch_lines(["* 4 passed in *"]) assert func_fix_setup == [True] * 4 assert class_fix_setup == [10, 20] - def test_parametrize_issue634(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_issue634(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1579,7 +1581,7 @@ class TestMetafuncFunctionalAuto: metafunc.parametrize('foo', params, indirect=True) """ ) - result = testdir.runpytest("-s") + result = pytester.runpytest("-s") output = result.stdout.str() assert output.count("preparing foo-2") == 1 assert output.count("preparing foo-3") == 1 @@ -1588,7 +1590,7 @@ class TestMetafuncFunctionalAuto: class TestMarkersWithParametrization: """#308""" - def test_simple_mark(self, testdir: Testdir) -> None: + def test_simple_mark(self, pytester: Pytester) -> None: s = """ import pytest @@ -1601,7 +1603,7 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - items = testdir.getitems(s) + items = pytester.getitems(s) assert len(items) == 3 for item in items: assert "foo" in item.keywords @@ -1609,7 +1611,7 @@ class TestMarkersWithParametrization: assert "bar" in items[1].keywords assert "bar" not in items[2].keywords - def test_select_based_on_mark(self, testdir: Testdir) -> None: + def test_select_based_on_mark(self, pytester: Pytester) -> None: s = """ import pytest @@ -1621,14 +1623,14 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - rec = testdir.inline_run("-m", "foo") + pytester.makepyfile(s) + rec = pytester.inline_run("-m", "foo") passed, skipped, fail = rec.listoutcomes() assert len(passed) == 1 assert len(skipped) == 0 assert len(fail) == 0 - def test_simple_xfail(self, testdir: Testdir) -> None: + def test_simple_xfail(self, pytester: Pytester) -> None: s = """ import pytest @@ -1640,12 +1642,12 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() # xfail is skip?? reprec.assertoutcome(passed=2, skipped=1) - def test_simple_xfail_single_argname(self, testdir: Testdir) -> None: + def test_simple_xfail_single_argname(self, pytester: Pytester) -> None: s = """ import pytest @@ -1657,11 +1659,11 @@ class TestMarkersWithParametrization: def test_isEven(n): assert n % 2 == 0 """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() reprec.assertoutcome(passed=2, skipped=1) - def test_xfail_with_arg(self, testdir: Testdir) -> None: + def test_xfail_with_arg(self, pytester: Pytester) -> None: s = """ import pytest @@ -1673,11 +1675,11 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() reprec.assertoutcome(passed=2, skipped=1) - def test_xfail_with_kwarg(self, testdir: Testdir) -> None: + def test_xfail_with_kwarg(self, pytester: Pytester) -> None: s = """ import pytest @@ -1689,11 +1691,11 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() reprec.assertoutcome(passed=2, skipped=1) - def test_xfail_with_arg_and_kwarg(self, testdir: Testdir) -> None: + def test_xfail_with_arg_and_kwarg(self, pytester: Pytester) -> None: s = """ import pytest @@ -1705,12 +1707,12 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() reprec.assertoutcome(passed=2, skipped=1) @pytest.mark.parametrize("strict", [True, False]) - def test_xfail_passing_is_xpass(self, testdir: Testdir, strict: bool) -> None: + def test_xfail_passing_is_xpass(self, pytester: Pytester, strict: bool) -> None: s = """ import pytest @@ -1726,12 +1728,12 @@ class TestMarkersWithParametrization: """.format( strict=strict ) - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() passed, failed = (2, 1) if strict else (3, 0) reprec.assertoutcome(passed=passed, failed=failed) - def test_parametrize_called_in_generate_tests(self, testdir: Testdir) -> None: + def test_parametrize_called_in_generate_tests(self, pytester: Pytester) -> None: s = """ import pytest @@ -1750,13 +1752,15 @@ class TestMarkersWithParametrization: def test_increment(n, expected): assert n + 1 == expected """ - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() reprec.assertoutcome(passed=2, skipped=2) - def test_parametrize_ID_generation_string_int_works(self, testdir: Testdir) -> None: + def test_parametrize_ID_generation_string_int_works( + self, pytester: Pytester + ) -> None: """#290""" - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1769,11 +1773,11 @@ class TestMarkersWithParametrization: return """ ) - reprec = testdir.inline_run() + reprec = pytester.inline_run() reprec.assertoutcome(passed=2) @pytest.mark.parametrize("strict", [True, False]) - def test_parametrize_marked_value(self, testdir: Testdir, strict: bool) -> None: + def test_parametrize_marked_value(self, pytester: Pytester, strict: bool) -> None: s = """ import pytest @@ -1792,19 +1796,19 @@ class TestMarkersWithParametrization: """.format( strict=strict ) - testdir.makepyfile(s) - reprec = testdir.inline_run() + pytester.makepyfile(s) + reprec = pytester.inline_run() passed, failed = (0, 2) if strict else (2, 0) reprec.assertoutcome(passed=passed, failed=failed) - def test_pytest_make_parametrize_id(self, testdir: Testdir) -> None: - testdir.makeconftest( + def test_pytest_make_parametrize_id(self, pytester: Pytester) -> None: + pytester.makeconftest( """ def pytest_make_parametrize_id(config, val): return str(val * 2) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1813,17 +1817,17 @@ class TestMarkersWithParametrization: pass """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines(["*test_func*0*PASS*", "*test_func*2*PASS*"]) - def test_pytest_make_parametrize_id_with_argname(self, testdir: Testdir) -> None: - testdir.makeconftest( + def test_pytest_make_parametrize_id_with_argname(self, pytester: Pytester) -> None: + pytester.makeconftest( """ def pytest_make_parametrize_id(config, val, argname): return str(val * 2 if argname == 'x' else val * 10) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1836,13 +1840,13 @@ class TestMarkersWithParametrization: pass """ ) - result = testdir.runpytest("-v") + result = pytester.runpytest("-v") result.stdout.fnmatch_lines( ["*test_func_a*0*PASS*", "*test_func_a*2*PASS*", "*test_func_b*10*PASS*"] ) - def test_parametrize_positional_args(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_positional_args(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest @@ -1851,11 +1855,11 @@ class TestMarkersWithParametrization: pass """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.assert_outcomes(passed=1) - def test_parametrize_iterator(self, testdir: Testdir) -> None: - testdir.makepyfile( + def test_parametrize_iterator(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import itertools import pytest @@ -1877,7 +1881,7 @@ class TestMarkersWithParametrization: pass """ ) - result = testdir.runpytest("-vv", "-s") + result = pytester.runpytest("-vv", "-s") result.stdout.fnmatch_lines( [ "test_parametrize_iterator.py::test1[param0] PASSED", diff --git a/testing/python/raises.py b/testing/python/raises.py index 80634eebf..a3991adae 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -3,6 +3,7 @@ import sys import pytest from _pytest.outcomes import Failed +from _pytest.pytester import Pytester class TestRaises: @@ -50,8 +51,8 @@ class TestRaises: pprint.pprint(excinfo) raise E() - def test_raises_as_contextmanager(self, testdir): - testdir.makepyfile( + def test_raises_as_contextmanager(self, pytester: Pytester) -> None: + pytester.makepyfile( """ import pytest import _pytest._code @@ -75,11 +76,11 @@ class TestRaises: 1/0 """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*3 passed*"]) - def test_does_not_raise(self, testdir): - testdir.makepyfile( + def test_does_not_raise(self, pytester: Pytester) -> None: + pytester.makepyfile( """ from contextlib import contextmanager import pytest @@ -100,11 +101,11 @@ class TestRaises: assert (6 / example_input) is not None """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*4 passed*"]) - def test_does_not_raise_does_raise(self, testdir): - testdir.makepyfile( + def test_does_not_raise_does_raise(self, pytester: Pytester) -> None: + pytester.makepyfile( """ from contextlib import contextmanager import pytest @@ -123,7 +124,7 @@ class TestRaises: assert (6 / example_input) is not None """ ) - result = testdir.runpytest() + result = pytester.runpytest() result.stdout.fnmatch_lines(["*2 failed*"]) def test_noclass(self) -> None: diff --git a/testing/python/show_fixtures_per_test.py b/testing/python/show_fixtures_per_test.py index ef841819d..2a1513273 100644 --- a/testing/python/show_fixtures_per_test.py +++ b/testing/python/show_fixtures_per_test.py @@ -1,11 +1,14 @@ -def test_no_items_should_not_show_output(testdir): - result = testdir.runpytest("--fixtures-per-test") +from _pytest.pytester import Pytester + + +def test_no_items_should_not_show_output(pytester: Pytester) -> None: + result = pytester.runpytest("--fixtures-per-test") result.stdout.no_fnmatch_line("*fixtures used by*") assert result.ret == 0 -def test_fixtures_in_module(testdir): - p = testdir.makepyfile( +def test_fixtures_in_module(pytester: Pytester) -> None: + p = pytester.makepyfile( ''' import pytest @pytest.fixture @@ -19,7 +22,7 @@ def test_fixtures_in_module(testdir): ''' ) - result = testdir.runpytest("--fixtures-per-test", p) + result = pytester.runpytest("--fixtures-per-test", p) assert result.ret == 0 result.stdout.fnmatch_lines( @@ -33,8 +36,8 @@ def test_fixtures_in_module(testdir): result.stdout.no_fnmatch_line("*_arg0*") -def test_fixtures_in_conftest(testdir): - testdir.makeconftest( +def test_fixtures_in_conftest(pytester: Pytester) -> None: + pytester.makeconftest( ''' import pytest @pytest.fixture @@ -50,7 +53,7 @@ def test_fixtures_in_conftest(testdir): """ ''' ) - p = testdir.makepyfile( + p = pytester.makepyfile( """ def test_arg2(arg2): pass @@ -58,7 +61,7 @@ def test_fixtures_in_conftest(testdir): pass """ ) - result = testdir.runpytest("--fixtures-per-test", p) + result = pytester.runpytest("--fixtures-per-test", p) assert result.ret == 0 result.stdout.fnmatch_lines( @@ -80,8 +83,8 @@ def test_fixtures_in_conftest(testdir): ) -def test_should_show_fixtures_used_by_test(testdir): - testdir.makeconftest( +def test_should_show_fixtures_used_by_test(pytester: Pytester) -> None: + pytester.makeconftest( ''' import pytest @pytest.fixture @@ -92,7 +95,7 @@ def test_should_show_fixtures_used_by_test(testdir): """arg2 from conftest""" ''' ) - p = testdir.makepyfile( + p = pytester.makepyfile( ''' import pytest @pytest.fixture @@ -102,7 +105,7 @@ def test_should_show_fixtures_used_by_test(testdir): pass ''' ) - result = testdir.runpytest("--fixtures-per-test", p) + result = pytester.runpytest("--fixtures-per-test", p) assert result.ret == 0 result.stdout.fnmatch_lines( @@ -117,8 +120,8 @@ def test_should_show_fixtures_used_by_test(testdir): ) -def test_verbose_include_private_fixtures_and_loc(testdir): - testdir.makeconftest( +def test_verbose_include_private_fixtures_and_loc(pytester: Pytester) -> None: + pytester.makeconftest( ''' import pytest @pytest.fixture @@ -129,7 +132,7 @@ def test_verbose_include_private_fixtures_and_loc(testdir): """arg2 from conftest""" ''' ) - p = testdir.makepyfile( + p = pytester.makepyfile( ''' import pytest @pytest.fixture @@ -139,7 +142,7 @@ def test_verbose_include_private_fixtures_and_loc(testdir): pass ''' ) - result = testdir.runpytest("--fixtures-per-test", "-v", p) + result = pytester.runpytest("--fixtures-per-test", "-v", p) assert result.ret == 0 result.stdout.fnmatch_lines( @@ -156,8 +159,8 @@ def test_verbose_include_private_fixtures_and_loc(testdir): ) -def test_doctest_items(testdir): - testdir.makepyfile( +def test_doctest_items(pytester: Pytester) -> None: + pytester.makepyfile( ''' def foo(): """ @@ -166,13 +169,13 @@ def test_doctest_items(testdir): """ ''' ) - testdir.maketxtfile( + pytester.maketxtfile( """ >>> 1 + 1 2 """ ) - result = testdir.runpytest( + result = pytester.runpytest( "--fixtures-per-test", "--doctest-modules", "--doctest-glob=*.txt", "-v" ) assert result.ret == 0