From 7845ab4bc3e689a9e2e9c17a763da69d299adc47 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 28 Jun 2018 14:36:35 +0200 Subject: [PATCH 1/5] remove test file formatting from TestContextManagerFixtureFuncs --- testing/python/fixture.py | 72 ++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 9cc3b6890..0c8c1a578 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -3462,25 +3462,40 @@ class TestShowFixtures(object): pass -@pytest.mark.parametrize("flavor", ["fixture", "yield_fixture"]) class TestContextManagerFixtureFuncs(object): + @pytest.fixture(params=["fixture", "yield_fixture"]) + def flavor(self, request, testdir, monkeypatch): + monkeypatch.setenv("PYTEST_FIXTURE_FLAVOR", request.param) + testdir.makepyfile( + test_context=""" + import os + import pytest + import warnings + VAR = "PYTEST_FIXTURE_FLAVOR" + if VAR not in os.environ: + warnings.warn("PYTEST_FIXTURE_FLAVOR was not set, assuming fixture") + fixture = pytest.fixture + else: + fixture = getattr(pytest, os.environ[VAR]) + """ + ) + def test_simple(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor} + from __future__ import print_function + from test_context import fixture + @fixture def arg1(): print ("setup") yield 1 print ("teardown") def test_1(arg1): - print ("test1 %s" % arg1) + print ("test1", arg1) def test_2(arg1): - print ("test2 %s" % arg1) + print ("test2", arg1) assert 0 - """.format( - flavor=flavor - ) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines( @@ -3497,19 +3512,18 @@ class TestContextManagerFixtureFuncs(object): def test_scoped(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor}(scope="module") + from __future__ import print_function + from test_context import fixture + @fixture(scope="module") def arg1(): print ("setup") yield 1 print ("teardown") def test_1(arg1): - print ("test1 %s" % arg1) + print ("test1", arg1) def test_2(arg1): - print ("test2 %s" % arg1) - """.format( - flavor=flavor - ) + print ("test2", arg1) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines( @@ -3524,16 +3538,14 @@ class TestContextManagerFixtureFuncs(object): def test_setup_exception(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor}(scope="module") + from test_context import fixture + @fixture(scope="module") def arg1(): pytest.fail("setup") yield 1 def test_1(arg1): pass - """.format( - flavor=flavor - ) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines( @@ -3546,16 +3558,14 @@ class TestContextManagerFixtureFuncs(object): def test_teardown_exception(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor}(scope="module") + from test_context import fixture + @fixture(scope="module") def arg1(): yield 1 pytest.fail("teardown") def test_1(arg1): pass - """.format( - flavor=flavor - ) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines( @@ -3568,8 +3578,8 @@ class TestContextManagerFixtureFuncs(object): def test_yields_more_than_one(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor}(scope="module") + from test_context import fixture + @fixture(scope="module") def arg1(): yield 1 yield 2 @@ -3590,15 +3600,13 @@ class TestContextManagerFixtureFuncs(object): def test_custom_name(self, testdir, flavor): testdir.makepyfile( """ - import pytest - @pytest.{flavor}(name='meow') + from test_context import fixture + @fixture(name='meow') def arg1(): return 'mew' def test_1(meow): print(meow) - """.format( - flavor=flavor - ) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines("*mew*") From 982b6140107c52c54e78df99293aa0e70a7d1619 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 28 Jun 2018 16:08:23 +0200 Subject: [PATCH 2/5] remove format calls for most fixture tests --- testing/python/fixture.py | 50 ++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 0c8c1a578..5e09fb83a 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -3585,9 +3585,7 @@ class TestContextManagerFixtureFuncs(object): yield 2 def test_1(arg1): pass - """.format( - flavor=flavor - ) + """ ) result = testdir.runpytest("-s") result.stdout.fnmatch_lines( @@ -3614,8 +3612,8 @@ class TestContextManagerFixtureFuncs(object): class TestParameterizedSubRequest(object): def test_call_from_fixture(self, testdir): - testfile = testdir.makepyfile( - """ + testdir.makepyfile( + test_call_from_fixture=""" import pytest @pytest.fixture(params=[0, 1, 2]) @@ -3636,18 +3634,16 @@ class TestParameterizedSubRequest(object): E*Failed: The requested fixture has no parameter defined for the current test. E* E*Requested fixture 'fix_with_param' defined in: - E*{}:4 + E*test_call_from_fixture.py:4 E*Requested here: - E*{}:9 + E*test_call_from_fixture.py:9 *1 error* - """.format( - testfile.basename, testfile.basename - ) + """ ) def test_call_from_test(self, testdir): - testfile = testdir.makepyfile( - """ + testdir.makepyfile( + test_call_from_test=""" import pytest @pytest.fixture(params=[0, 1, 2]) @@ -3664,17 +3660,15 @@ class TestParameterizedSubRequest(object): E*Failed: The requested fixture has no parameter defined for the current test. E* E*Requested fixture 'fix_with_param' defined in: - E*{}:4 + E*test_call_from_test.py:4 E*Requested here: - E*{}:8 + E*test_call_from_test.py:8 *1 failed* - """.format( - testfile.basename, testfile.basename - ) + """ ) def test_external_fixture(self, testdir): - conffile = testdir.makeconftest( + testdir.makeconftest( """ import pytest @@ -3684,8 +3678,8 @@ class TestParameterizedSubRequest(object): """ ) - testfile = testdir.makepyfile( - """ + testdir.makepyfile( + test_external_fixture=""" def test_foo(request): request.getfixturevalue('fix_with_param') """ @@ -3696,13 +3690,11 @@ class TestParameterizedSubRequest(object): E*Failed: The requested fixture has no parameter defined for the current test. E* E*Requested fixture 'fix_with_param' defined in: - E*{}:4 + E*conftest.py:4 E*Requested here: - E*{}:2 + E*test_external_fixture.py:2 *1 failed* - """.format( - conffile.basename, testfile.basename - ) + """ ) def test_non_relative_path(self, testdir): @@ -3741,13 +3733,11 @@ class TestParameterizedSubRequest(object): E*Failed: The requested fixture has no parameter defined for the current test. E* E*Requested fixture 'fix_with_param' defined in: - E*{}:5 + E*fix.py:5 E*Requested here: - E*{}:5 + E*test_foos.py:5 *1 failed* - """.format( - fixfile.strpath, testfile.basename - ) + """ ) From 5582ad0445029672daf0f18fb12a3d940dbc6bb7 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 28 Jun 2018 16:50:06 +0200 Subject: [PATCH 3/5] remove use of formatting in test_func_closure_module_auto this makes it apparent that pytester should supply some kind of variable support --- testing/python/fixture.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 5e09fb83a..42f637776 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -3790,17 +3790,28 @@ def test_pytest_fixture_setup_and_post_finalizer_hook(testdir): class TestScopeOrdering(object): """Class of tests that ensure fixtures are ordered based on their scopes (#2405)""" - @pytest.mark.parametrize("use_mark", [True, False]) - def test_func_closure_module_auto(self, testdir, use_mark): + @pytest.mark.parametrize("variant", ["mark", "autouse"]) + @pytest.mark.issue(github="#2405") + def test_func_closure_module_auto(self, testdir, variant, monkeypatch): """Semantically identical to the example posted in #2405 when ``use_mark=True``""" + monkeypatch.setenv("FIXTURE_ACTIVATION_VARIANT", variant) testdir.makepyfile( """ + import warnings + import os import pytest + VAR = 'FIXTURE_ACTIVATION_VARIANT' + VALID_VARS = ('autouse', 'mark') - @pytest.fixture(scope='module', autouse={autouse}) + VARIANT = os.environ.get(VAR) + if VARIANT is None or VARIANT not in VALID_VARS: + warnings.warn(\"{!r}\" is not in {}, assuming autouse".format(VARIANT, VALID_VARS) ) + variant = 'mark' + + @pytest.fixture(scope='module', autouse=VARIANT == 'autouse') def m1(): pass - if {use_mark}: + if VARIANT=='mark': pytestmark = pytest.mark.usefixtures('m1') @pytest.fixture(scope='function', autouse=True) @@ -3808,9 +3819,7 @@ class TestScopeOrdering(object): def test_func(m1): pass - """.format( - autouse=not use_mark, use_mark=use_mark - ) + """ ) items, _ = testdir.inline_genitems() request = FixtureRequest(items[0]) From 4ae7e9788c67cb723ccfa7f1a5987d6db451b27b Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 29 Jun 2018 07:13:18 +0200 Subject: [PATCH 4/5] fix quotes in scope order test --- testing/python/fixture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 42f637776..4834bc3df 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -3805,7 +3805,7 @@ class TestScopeOrdering(object): VARIANT = os.environ.get(VAR) if VARIANT is None or VARIANT not in VALID_VARS: - warnings.warn(\"{!r}\" is not in {}, assuming autouse".format(VARIANT, VALID_VARS) ) + warnings.warn("{!r} is not in {}, assuming autouse".format(VARIANT, VALID_VARS) ) variant = 'mark' @pytest.fixture(scope='module', autouse=VARIANT == 'autouse') From 0fd86ec8a815dc84522d4407c8b6aa912153663b Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Fri, 29 Jun 2018 10:58:33 +0200 Subject: [PATCH 5/5] move some fill fixture acceptance tests contents to the examples script folder --- src/_pytest/pytester.py | 46 ++++- .../sub1/__init__.py | 0 .../sub1/conftest.py | 7 + .../sub1/test_in_sub1.py | 2 + .../sub2/__init__.py | 0 .../sub2/conftest.py | 7 + .../sub2/test_in_sub2.py | 2 + .../conftest.py | 6 + .../pkg/__init__.py | 0 .../pkg/conftest.py | 6 + .../pkg/test_spam.py | 2 + .../conftest.py | 6 + .../test_extend_fixture_conftest_module.py | 10 ++ .../test_extend_fixture_module_class.py | 15 ++ .../fill_fixtures/test_funcarg_basic.py | 16 ++ .../test_funcarg_lookup_classlevel.py | 11 ++ .../test_funcarg_lookup_modulelevel.py | 15 ++ .../fill_fixtures/test_funcarg_lookupfails.py | 10 ++ testing/python/fixture.py | 169 ++---------------- 19 files changed, 170 insertions(+), 160 deletions(-) create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/__init__.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/__init__.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/__init__.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py create mode 100644 testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 58e4d5d54..08a02f6f5 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -21,7 +21,7 @@ import py import pytest from _pytest.main import Session, EXIT_OK from _pytest.assertion.rewrite import AssertionRewritingHook - +from _pytest.compat import Path PYTEST_FULLPATH = os.path.abspath(pytest.__file__.rstrip("oc")).replace( "$py.class", ".py" @@ -632,7 +632,7 @@ class Testdir(object): p.ensure("__init__.py") return p - def copy_example(self, name): + def copy_example(self, name=None): from . import experiments import warnings @@ -640,11 +640,37 @@ class Testdir(object): example_dir = self.request.config.getini("pytester_example_dir") if example_dir is None: raise ValueError("pytester_example_dir is unset, can't copy examples") - example_path = self.request.config.rootdir.join(example_dir, name) + example_dir = self.request.config.rootdir.join(example_dir) + + for extra_element in self.request.node.iter_markers("pytester_example_path"): + assert extra_element.args + example_dir = example_dir.join(*extra_element.args) + + if name is None: + func_name = self.request.function.__name__ + maybe_dir = example_dir / func_name + maybe_file = example_dir / (func_name + ".py") + + if maybe_dir.isdir(): + example_path = maybe_dir + elif maybe_file.isfile(): + example_path = maybe_file + else: + raise LookupError( + "{} cant be found as module or package in {}".format( + func_name, example_dir.bestrelpath(self.request.confg.rootdir) + ) + ) + else: + example_path = example_dir.join(name) + if example_path.isdir() and not example_path.join("__init__.py").isfile(): example_path.copy(self.tmpdir) + return self.tmpdir elif example_path.isfile(): - example_path.copy(self.tmpdir.join(example_path.basename)) + result = self.tmpdir.join(example_path.basename) + example_path.copy(result) + return result else: raise LookupError("example is not found as a file or directory") @@ -954,14 +980,16 @@ class Testdir(object): same directory to ensure it is a package """ - kw = {self.request.function.__name__: Source(source).strip()} - path = self.makepyfile(**kw) + if isinstance(source, Path): + path = self.tmpdir.join(str(source)) + assert not withinit, "not supported for paths" + else: + kw = {self.request.function.__name__: Source(source).strip()} + path = self.makepyfile(**kw) if withinit: self.makepyfile(__init__="#") self.config = config = self.parseconfigure(path, *configargs) - node = self.getnode(config, path) - - return node + return self.getnode(config, path) def collect_by_name(self, modcol, name): """Return the collection node for name from the module collection. diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/__init__.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py new file mode 100644 index 000000000..79af4bc47 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py @@ -0,0 +1,7 @@ +import pytest + + +@pytest.fixture +def arg1(request): + with pytest.raises(Exception): + request.getfixturevalue("arg2") diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py new file mode 100644 index 000000000..df36da136 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py @@ -0,0 +1,2 @@ +def test_1(arg1): + pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/__init__.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py new file mode 100644 index 000000000..927ecc4d1 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py @@ -0,0 +1,7 @@ + +import pytest + + +@pytest.fixture +def arg2(request): + pytest.raises(Exception, "request.getfixturevalue('arg1')") diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py new file mode 100644 index 000000000..1c34f94ac --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py @@ -0,0 +1,2 @@ +def test_2(arg2): + pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py new file mode 100644 index 000000000..5dfd2f779 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture +def spam(): + return "spam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/__init__.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py new file mode 100644 index 000000000..4e22ce5a1 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture +def spam(spam): + return spam * 2 diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py new file mode 100644 index 000000000..0d891fbb5 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py @@ -0,0 +1,2 @@ +def test_spam(spam): + assert spam == "spamspam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py new file mode 100644 index 000000000..5dfd2f779 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture +def spam(): + return "spam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py new file mode 100644 index 000000000..46d1446f4 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py @@ -0,0 +1,10 @@ +import pytest + + +@pytest.fixture +def spam(spam): + return spam * 2 + + +def test_spam(spam): + assert spam == "spamspam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py new file mode 100644 index 000000000..2b8218ed7 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py @@ -0,0 +1,15 @@ +import pytest + + +@pytest.fixture +def spam(): + return "spam" + + +class TestSpam(object): + @pytest.fixture + def spam(self, spam): + return spam * 2 + + def test_spam(self, spam): + assert spam == "spamspam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py new file mode 100644 index 000000000..983849dba --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py @@ -0,0 +1,16 @@ + +import pytest + + +@pytest.fixture +def some(request): + return request.function.__name__ + + +@pytest.fixture +def other(request): + return 42 + + +def test_func(some, other): + pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py new file mode 100644 index 000000000..56b8d0c7f --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py @@ -0,0 +1,11 @@ + +import pytest + + +class TestClass(object): + @pytest.fixture + def something(self, request): + return request.instance + + def test_method(self, something): + assert something is self diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py new file mode 100644 index 000000000..227abb593 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py @@ -0,0 +1,15 @@ +import pytest + + +@pytest.fixture +def something(request): + return request.function.__name__ + + +class TestClass(object): + def test_method(self, something): + assert something == "test_method" + + +def test_func(something): + assert something == "test_func" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py new file mode 100644 index 000000000..b77520323 --- /dev/null +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py @@ -0,0 +1,10 @@ +import pytest + + +@pytest.fixture +def xyzsomething(request): + return 42 + + +def test_func(some): + pass diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 4834bc3df..ef2a77652 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -5,6 +5,7 @@ import pytest from _pytest.pytester import get_public_names from _pytest.fixtures import FixtureLookupError, FixtureRequest from _pytest import fixtures +from _pytest.compat import Path def test_getfuncargnames(): @@ -40,45 +41,27 @@ def test_getfuncargnames(): assert fixtures.getfuncargnames(A.static, cls=A) == ("arg1", "arg2") +@pytest.mark.pytester_example_path("fixtures/fill_fixtures") class TestFillFixtures(object): def test_fillfuncargs_exposed(self): # used by oejskit, kept for compatibility assert pytest._fillfuncargs == fixtures.fillfixtures def test_funcarg_lookupfails(self, testdir): - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def xyzsomething(request): - return 42 - - def test_func(some): - pass - """ - ) + testdir.copy_example() result = testdir.runpytest() # "--collect-only") assert result.ret != 0 result.stdout.fnmatch_lines( - ["*def test_func(some)*", "*fixture*some*not found*", "*xyzsomething*"] + """ + *def test_func(some)* + *fixture*some*not found* + *xyzsomething* + """ ) def test_funcarg_basic(self, testdir): - item = testdir.getitem( - """ - import pytest - - @pytest.fixture - def some(request): - return request.function.__name__ - @pytest.fixture - def other(request): - return 42 - def test_func(some, other): - pass - """ - ) + testdir.copy_example() + item = testdir.getitem(Path("test_funcarg_basic.py")) fixtures.fillfixtures(item) del item.funcargs["request"] assert len(get_public_names(item.funcargs)) == 2 @@ -86,155 +69,39 @@ class TestFillFixtures(object): assert item.funcargs["other"] == 42 def test_funcarg_lookup_modulelevel(self, testdir): - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def something(request): - return request.function.__name__ - - class TestClass(object): - def test_method(self, something): - assert something == "test_method" - def test_func(something): - assert something == "test_func" - """ - ) + testdir.copy_example() reprec = testdir.inline_run() reprec.assertoutcome(passed=2) def test_funcarg_lookup_classlevel(self, testdir): - p = testdir.makepyfile( - """ - import pytest - class TestClass(object): - - @pytest.fixture - def something(self, request): - return request.instance - - def test_method(self, something): - assert something is self - """ - ) + p = testdir.copy_example() result = testdir.runpytest(p) result.stdout.fnmatch_lines(["*1 passed*"]) def test_conftest_funcargs_only_available_in_subdir(self, testdir): - sub1 = testdir.mkpydir("sub1") - sub2 = testdir.mkpydir("sub2") - sub1.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest - @pytest.fixture - def arg1(request): - pytest.raises(Exception, "request.getfixturevalue('arg2')") - """ - ) - ) - sub2.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest - @pytest.fixture - def arg2(request): - pytest.raises(Exception, "request.getfixturevalue('arg1')") - """ - ) - ) - - sub1.join("test_in_sub1.py").write("def test_1(arg1): pass") - sub2.join("test_in_sub2.py").write("def test_2(arg2): pass") + testdir.copy_example() result = testdir.runpytest("-v") result.assert_outcomes(passed=2) def test_extend_fixture_module_class(self, testdir): - testfile = testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def spam(): - return 'spam' - - class TestSpam(object): - - @pytest.fixture - def spam(self, spam): - return spam * 2 - - def test_spam(self, spam): - assert spam == 'spamspam' - """ - ) + testfile = testdir.copy_example() result = testdir.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) result = testdir.runpytest(testfile) result.stdout.fnmatch_lines(["*1 passed*"]) def test_extend_fixture_conftest_module(self, testdir): - testdir.makeconftest( - """ - import pytest - - @pytest.fixture - def spam(): - return 'spam' - """ - ) - testfile = testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def spam(spam): - return spam * 2 - - def test_spam(spam): - assert spam == 'spamspam' - """ - ) + p = testdir.copy_example() result = testdir.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(testfile) + result = testdir.runpytest(next(p.visit("test_*.py"))) result.stdout.fnmatch_lines(["*1 passed*"]) def test_extend_fixture_conftest_conftest(self, testdir): - testdir.makeconftest( - """ - import pytest - - @pytest.fixture - def spam(): - return 'spam' - """ - ) - pkg = testdir.mkpydir("pkg") - pkg.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest - - @pytest.fixture - def spam(spam): - return spam * 2 - """ - ) - ) - testfile = pkg.join("test_spam.py") - testfile.write( - _pytest._code.Source( - """ - def test_spam(spam): - assert spam == "spamspam" - """ - ) - ) + p = testdir.copy_example() result = testdir.runpytest() result.stdout.fnmatch_lines(["*1 passed*"]) - result = testdir.runpytest(testfile) + result = testdir.runpytest(next(p.visit("test_*.py"))) result.stdout.fnmatch_lines(["*1 passed*"]) def test_extend_fixture_conftest_plugin(self, testdir):