Merge pull request #1714 from nicoddemus/deprecate-yield-tests-funcarg-prefix

Deprecate yield tests funcarg prefix
This commit is contained in:
Ronny Pfannschmidt 2016-07-12 11:43:59 +02:00 committed by GitHub
commit 4c56c95eb8
24 changed files with 284 additions and 108 deletions

View File

@ -40,7 +40,8 @@
2])`` only ran once. Now a failure is raised. Fixes `#460`_. Thanks to 2])`` only ran once. Now a failure is raised. Fixes `#460`_. Thanks to
`@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for PR. `@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for PR.
* * ``_pytest.monkeypatch.monkeypatch`` class has been renamed to ``_pytest.monkeypatch.MonkeyPatch``
so it doesn't conflict with the ``monkeypatch`` fixture.
* *
@ -185,9 +186,12 @@
Before, you only got exceptions later from ``argparse`` library, Before, you only got exceptions later from ``argparse`` library,
giving no clue about the actual reason for double-added options. giving no clue about the actual reason for double-added options.
* * ``yield``-based tests are considered deprecated and will be removed in pytest-4.0.
Thanks `@nicoddemus`_ for the PR.
* * Using ``pytest_funcarg__`` prefix to declare fixtures is considered deprecated and will be
removed in pytest-4.0 (`#1684`_).
Thanks `@nicoddemus`_ for the PR.
* *
@ -261,6 +265,7 @@
.. _#1632: https://github.com/pytest-dev/pytest/issues/1632 .. _#1632: https://github.com/pytest-dev/pytest/issues/1632
.. _#1633: https://github.com/pytest-dev/pytest/pull/1633 .. _#1633: https://github.com/pytest-dev/pytest/pull/1633
.. _#1664: https://github.com/pytest-dev/pytest/pull/1664 .. _#1664: https://github.com/pytest-dev/pytest/pull/1664
.. _#1684: https://github.com/pytest-dev/pytest/pull/1684
.. _@DRMacIver: https://github.com/DRMacIver .. _@DRMacIver: https://github.com/DRMacIver
.. _@RedBeardCode: https://github.com/RedBeardCode .. _@RedBeardCode: https://github.com/RedBeardCode

View File

@ -6,7 +6,7 @@ import os
import sys import sys
from _pytest.config import hookimpl from _pytest.config import hookimpl
from _pytest.monkeypatch import monkeypatch from _pytest.monkeypatch import MonkeyPatch
from _pytest.assertion import util from _pytest.assertion import util
@ -56,7 +56,7 @@ def pytest_load_initial_conftests(early_config, parser, args):
if mode != "plain": if mode != "plain":
_load_modules(mode) _load_modules(mode)
m = monkeypatch() m = MonkeyPatch()
early_config._cleanup.append(m.undo) early_config._cleanup.append(m.undo)
m.setattr(py.builtin.builtins, 'AssertionError', m.setattr(py.builtin.builtins, 'AssertionError',
reinterpret.AssertionError) # noqa reinterpret.AssertionError) # noqa

View File

@ -865,6 +865,10 @@ def yield_fixture(scope="function", params=None, autouse=False, ids=None, name=N
return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name) return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
defaultfuncargprefixmarker = fixture() defaultfuncargprefixmarker = fixture()
funcarg_prefix_warning = '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' \
'and scheduled to be removed in pytest 4.0.\n' \
'remove the prefix and use the @pytest.fixture decorator instead'
@fixture(scope="session") @fixture(scope="session")
@ -1042,6 +1046,7 @@ class FixtureManager:
if not callable(obj): if not callable(obj):
continue continue
marker = defaultfuncargprefixmarker marker = defaultfuncargprefixmarker
self.config.warn('C1', funcarg_prefix_warning.format(name=name))
name = name[len(self._argprefix):] name = name[len(self._argprefix):]
elif not isinstance(marker, FixtureFunctionMarker): elif not isinstance(marker, FixtureFunctionMarker):
# magic globals with __getattr__ might have got us a wrong # magic globals with __getattr__ might have got us a wrong
@ -1050,7 +1055,9 @@ class FixtureManager:
else: else:
if marker.name: if marker.name:
name = marker.name name = marker.name
assert not name.startswith(self._argprefix), name msg = 'fixtures cannot have "pytest_funcarg__" prefix ' \
'and be decorated with @pytest.fixture:\n%s' % name
assert not name.startswith(self._argprefix), msg
fixturedef = FixtureDef(self, nodeid, name, obj, fixturedef = FixtureDef(self, nodeid, name, obj,
marker.scope, marker.params, marker.scope, marker.params,
unittest=unittest, ids=marker.ids) unittest=unittest, ids=marker.ids)

View File

@ -5,11 +5,14 @@ import re
from py.builtin import _basestring from py.builtin import _basestring
import pytest
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$") RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
def pytest_funcarg__monkeypatch(request): @pytest.fixture
"""The returned ``monkeypatch`` funcarg provides these def monkeypatch(request):
"""The returned ``monkeypatch`` fixture provides these
helper methods to modify objects, dictionaries or os.environ:: helper methods to modify objects, dictionaries or os.environ::
monkeypatch.setattr(obj, name, value, raising=True) monkeypatch.setattr(obj, name, value, raising=True)
@ -26,7 +29,7 @@ def pytest_funcarg__monkeypatch(request):
parameter determines if a KeyError or AttributeError parameter determines if a KeyError or AttributeError
will be raised if the set/deletion operation has no target. will be raised if the set/deletion operation has no target.
""" """
mpatch = monkeypatch() mpatch = MonkeyPatch()
request.addfinalizer(mpatch.undo) request.addfinalizer(mpatch.undo)
return mpatch return mpatch
@ -93,7 +96,7 @@ class Notset:
notset = Notset() notset = Notset()
class monkeypatch: class MonkeyPatch:
""" Object keeping a record of setattr/item/env/syspath changes. """ """ Object keeping a record of setattr/item/env/syspath changes. """
def __init__(self): def __init__(self):

View File

@ -321,7 +321,8 @@ def linecomp(request):
return LineComp() return LineComp()
def pytest_funcarg__LineMatcher(request): @pytest.fixture(name='LineMatcher')
def LineMatcher_fixture(request):
return LineMatcher return LineMatcher

View File

@ -589,6 +589,8 @@ class Generator(FunctionMixin, PyCollector):
raise ValueError("%r generated tests with non-unique name %r" %(self, name)) raise ValueError("%r generated tests with non-unique name %r" %(self, name))
seen[name] = True seen[name] = True
l.append(self.Function(name, self, args=args, callobj=call)) l.append(self.Function(name, self, args=args, callobj=call))
msg = 'yield tests are deprecated, and scheduled to be removed in pytest 4.0'
self.config.warn('C1', msg, fslocation=self.fspath)
return l return l
def getcallargs(self, obj): def getcallargs(self, obj):
@ -611,8 +613,6 @@ def hasinit(obj):
return True return True
class CallSpec2(object): class CallSpec2(object):
def __init__(self, metafunc): def __init__(self, metafunc):
self.metafunc = metafunc self.metafunc = metafunc

View File

@ -3,7 +3,7 @@ import re
import pytest import pytest
import py import py
from _pytest.monkeypatch import monkeypatch from _pytest.monkeypatch import MonkeyPatch
class TempdirFactory: class TempdirFactory:
@ -92,7 +92,7 @@ def pytest_configure(config):
available at pytest_configure time, but ideally should be moved entirely available at pytest_configure time, but ideally should be moved entirely
to the tmpdir_factory session fixture. to the tmpdir_factory session fixture.
""" """
mp = monkeypatch() mp = MonkeyPatch()
t = TempdirFactory(config) t = TempdirFactory(config)
config._cleanup.extend([mp.undo, t.finish]) config._cleanup.extend([mp.undo, t.finish])
mp.setattr(config, '_tmpdirhandler', t, raising=False) mp.setattr(config, '_tmpdirhandler', t, raising=False)

View File

@ -762,3 +762,34 @@ class TestDurationWithFixture:
* setup *test_1* * setup *test_1*
* call *test_1* * call *test_1*
""") """)
def test_yield_tests_deprecation(testdir):
testdir.makepyfile("""
def func1(arg, arg2):
assert arg == arg2
def test_gen():
yield "m1", func1, 15, 3*5
yield "m2", func1, 42, 6*7
""")
result = testdir.runpytest('-ra')
result.stdout.fnmatch_lines([
'*yield tests are deprecated, and scheduled to be removed in pytest 4.0*',
'*2 passed*',
])
def test_funcarg_prefix_deprecation(testdir):
testdir.makepyfile("""
def pytest_funcarg__value():
return 10
def test_funcarg_prefix(value):
assert value == 10
""")
result = testdir.runpytest('-ra')
result.stdout.fnmatch_lines([
'*declaring fixtures using "pytest_funcarg__" prefix is deprecated and scheduled to be removed in pytest 4.0*',
'*remove the prefix and use the @pytest.fixture decorator instead*',
'*1 passed*',
])

View File

@ -381,7 +381,9 @@ def test_match_raises_error(testdir):
]) ])
class TestFormattedExcinfo: class TestFormattedExcinfo:
def pytest_funcarg__importasmod(self, request):
@pytest.fixture
def importasmod(self, request):
def importasmod(source): def importasmod(source):
source = _pytest._code.Source(source) source = _pytest._code.Source(source)
tmpdir = request.getfixturevalue("tmpdir") tmpdir = request.getfixturevalue("tmpdir")

View File

@ -285,13 +285,14 @@ class TestSourceParsingAndCompiling:
#print "block", str(block) #print "block", str(block)
assert str(stmt).strip().startswith('assert') assert str(stmt).strip().startswith('assert')
def test_compilefuncs_and_path_sanity(self): @pytest.mark.parametrize('name', ['', None, 'my'])
def test_compilefuncs_and_path_sanity(self, name):
def check(comp, name): def check(comp, name):
co = comp(self.source, name) co = comp(self.source, name)
if not name: if not name:
expected = "codegen %s:%d>" %(mypath, mylineno+2+1) expected = "codegen %s:%d>" %(mypath, mylineno+2+2)
else: else:
expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+1) expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+2)
fn = co.co_filename fn = co.co_filename
assert fn.endswith(expected) assert fn.endswith(expected)
@ -300,8 +301,7 @@ class TestSourceParsingAndCompiling:
mypath = mycode.path mypath = mycode.path
for comp in _pytest._code.compile, _pytest._code.Source.compile: for comp in _pytest._code.compile, _pytest._code.Source.compile:
for name in '', None, 'my': check(comp, name)
yield check, comp, name
def test_offsetless_synerr(self): def test_offsetless_synerr(self):
pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode='eval') pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode='eval')

View File

@ -795,21 +795,24 @@ class TestTracebackCutting:
def test_traceback_argsetup(self, testdir): def test_traceback_argsetup(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
def pytest_funcarg__hello(request): import pytest
@pytest.fixture
def hello(request):
raise ValueError("xyz") raise ValueError("xyz")
""") """)
p = testdir.makepyfile("def test(hello): pass") p = testdir.makepyfile("def test(hello): pass")
result = testdir.runpytest(p) result = testdir.runpytest(p)
assert result.ret != 0 assert result.ret != 0
out = result.stdout.str() out = result.stdout.str()
assert out.find("xyz") != -1 assert "xyz" in out
assert out.find("conftest.py:2: ValueError") != -1 assert "conftest.py:5: ValueError" in out
numentries = out.count("_ _ _") # separator for traceback entries numentries = out.count("_ _ _") # separator for traceback entries
assert numentries == 0 assert numentries == 0
result = testdir.runpytest("--fulltrace", p) result = testdir.runpytest("--fulltrace", p)
out = result.stdout.str() out = result.stdout.str()
assert out.find("conftest.py:2: ValueError") != -1 assert "conftest.py:5: ValueError" in out
numentries = out.count("_ _ _ _") # separator for traceback entries numentries = out.count("_ _ _ _") # separator for traceback entries
assert numentries > 3 assert numentries > 3

View File

@ -30,7 +30,10 @@ class TestFillFixtures:
def test_funcarg_lookupfails(self, testdir): def test_funcarg_lookupfails(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__xyzsomething(request): import pytest
@pytest.fixture
def xyzsomething(request):
return 42 return 42
def test_func(some): def test_func(some):
@ -46,9 +49,13 @@ class TestFillFixtures:
def test_funcarg_basic(self, testdir): def test_funcarg_basic(self, testdir):
item = testdir.getitem(""" item = testdir.getitem("""
def pytest_funcarg__some(request): import pytest
@pytest.fixture
def some(request):
return request.function.__name__ return request.function.__name__
def pytest_funcarg__other(request): @pytest.fixture
def other(request):
return 42 return 42
def test_func(some, other): def test_func(some, other):
pass pass
@ -61,7 +68,10 @@ class TestFillFixtures:
def test_funcarg_lookup_modulelevel(self, testdir): def test_funcarg_lookup_modulelevel(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
return request.function.__name__ return request.function.__name__
class TestClass: class TestClass:
@ -75,9 +85,13 @@ class TestFillFixtures:
def test_funcarg_lookup_classlevel(self, testdir): def test_funcarg_lookup_classlevel(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
import pytest
class TestClass: class TestClass:
def pytest_funcarg__something(self, request):
@pytest.fixture
def something(self, request):
return request.instance return request.instance
def test_method(self, something): def test_method(self, something):
assert something is self assert something is self
""") """)
@ -91,12 +105,14 @@ class TestFillFixtures:
sub2 = testdir.mkpydir("sub2") sub2 = testdir.mkpydir("sub2")
sub1.join("conftest.py").write(_pytest._code.Source(""" sub1.join("conftest.py").write(_pytest._code.Source("""
import pytest import pytest
def pytest_funcarg__arg1(request): @pytest.fixture
def arg1(request):
pytest.raises(Exception, "request.getfixturevalue('arg2')") pytest.raises(Exception, "request.getfixturevalue('arg2')")
""")) """))
sub2.join("conftest.py").write(_pytest._code.Source(""" sub2.join("conftest.py").write(_pytest._code.Source("""
import pytest import pytest
def pytest_funcarg__arg2(request): @pytest.fixture
def arg2(request):
pytest.raises(Exception, "request.getfixturevalue('arg1')") pytest.raises(Exception, "request.getfixturevalue('arg1')")
""")) """))
@ -396,7 +412,10 @@ class TestFillFixtures:
class TestRequestBasic: class TestRequestBasic:
def test_request_attributes(self, testdir): def test_request_attributes(self, testdir):
item = testdir.getitem(""" item = testdir.getitem("""
def pytest_funcarg__something(request): pass import pytest
@pytest.fixture
def something(request): pass
def test_func(something): pass def test_func(something): pass
""") """)
req = fixtures.FixtureRequest(item) req = fixtures.FixtureRequest(item)
@ -410,8 +429,11 @@ class TestRequestBasic:
def test_request_attributes_method(self, testdir): def test_request_attributes_method(self, testdir):
item, = testdir.getitems(""" item, = testdir.getitems("""
import pytest
class TestB: class TestB:
def pytest_funcarg__something(self, request):
@pytest.fixture
def something(self, request):
return 1 return 1
def test_func(self, something): def test_func(self, something):
pass pass
@ -420,9 +442,11 @@ class TestRequestBasic:
assert req.cls.__name__ == "TestB" assert req.cls.__name__ == "TestB"
assert req.instance.__class__ == req.cls assert req.instance.__class__ == req.cls
def XXXtest_request_contains_funcarg_arg2fixturedefs(self, testdir): def test_request_contains_funcarg_arg2fixturedefs(self, testdir):
modcol = testdir.getmodulecol(""" modcol = testdir.getmodulecol("""
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
pass pass
class TestClass: class TestClass:
def test_method(self, something): def test_method(self, something):
@ -432,15 +456,21 @@ class TestRequestBasic:
assert item1.name == "test_method" assert item1.name == "test_method"
arg2fixturedefs = fixtures.FixtureRequest(item1)._arg2fixturedefs arg2fixturedefs = fixtures.FixtureRequest(item1)._arg2fixturedefs
assert len(arg2fixturedefs) == 1 assert len(arg2fixturedefs) == 1
assert arg2fixturedefs[0].__name__ == "pytest_funcarg__something" assert arg2fixturedefs['something'][0].argname == "something"
def test_getfixturevalue_recursive(self, testdir): def test_getfixturevalue_recursive(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
return 1 return 1
""") """)
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
return request.getfixturevalue("something") + 1 return request.getfixturevalue("something") + 1
def test_func(something): def test_func(something):
assert something == 2 assert something == 2
@ -452,9 +482,12 @@ class TestRequestBasic:
'getfixmethod', ('getfixturevalue', 'getfuncargvalue')) 'getfixmethod', ('getfixturevalue', 'getfuncargvalue'))
def test_getfixturevalue(self, testdir, getfixmethod): def test_getfixturevalue(self, testdir, getfixmethod):
item = testdir.getitem(""" item = testdir.getitem("""
import pytest
l = [2] l = [2]
def pytest_funcarg__something(request): return 1 @pytest.fixture
def pytest_funcarg__other(request): def something(request): return 1
@pytest.fixture
def other(request):
return l.pop() return l.pop()
def test_func(something): pass def test_func(something): pass
""") """)
@ -477,8 +510,10 @@ class TestRequestBasic:
def test_request_addfinalizer(self, testdir): def test_request_addfinalizer(self, testdir):
item = testdir.getitem(""" item = testdir.getitem("""
import pytest
teardownlist = [] teardownlist = []
def pytest_funcarg__something(request): @pytest.fixture
def something(request):
request.addfinalizer(lambda: teardownlist.append(1)) request.addfinalizer(lambda: teardownlist.append(1))
def test_func(something): pass def test_func(something): pass
""") """)
@ -503,7 +538,8 @@ class TestRequestBasic:
result = testdir.runpytest_subprocess() result = testdir.runpytest_subprocess()
assert result.ret != 0 assert result.ret != 0
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"*AssertionError:*pytest_funcarg__marked_with_prefix_and_decorator*" "*AssertionError: fixtures cannot have*@pytest.fixture*",
"*pytest_funcarg__marked_with_prefix_and_decorator*"
]) ])
def test_request_addfinalizer_failing_setup(self, testdir): def test_request_addfinalizer_failing_setup(self, testdir):
@ -541,8 +577,10 @@ class TestRequestBasic:
def test_request_addfinalizer_partial_setup_failure(self, testdir): def test_request_addfinalizer_partial_setup_failure(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
import pytest
l = [] l = []
def pytest_funcarg__something(request): @pytest.fixture
def something(request):
request.addfinalizer(lambda: l.append(None)) request.addfinalizer(lambda: l.append(None))
def test_func(something, missingarg): def test_func(something, missingarg):
pass pass
@ -583,9 +621,11 @@ class TestRequestBasic:
def test_funcargnames_compatattr(self, testdir): def test_funcargnames_compatattr(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
assert metafunc.funcargnames == metafunc.fixturenames assert metafunc.funcargnames == metafunc.fixturenames
def pytest_funcarg__fn(request): @pytest.fixture
def fn(request):
assert request._pyfuncitem.funcargnames == \ assert request._pyfuncitem.funcargnames == \
request._pyfuncitem.fixturenames request._pyfuncitem.fixturenames
return request.funcargnames, request.fixturenames return request.funcargnames, request.fixturenames
@ -630,7 +670,9 @@ class TestRequestBasic:
# this tests that normalization of nodeids takes place # this tests that normalization of nodeids takes place
b = testdir.mkdir("tests").mkdir("unit") b = testdir.mkdir("tests").mkdir("unit")
b.join("conftest.py").write(_pytest._code.Source(""" b.join("conftest.py").write(_pytest._code.Source("""
def pytest_funcarg__arg1(): import pytest
@pytest.fixture
def arg1():
pass pass
""")) """))
p = b.join("test_module.py") p = b.join("test_module.py")
@ -678,7 +720,10 @@ class TestRequestBasic:
class TestRequestMarking: class TestRequestMarking:
def test_applymarker(self, testdir): def test_applymarker(self, testdir):
item1,item2 = testdir.getitems(""" item1,item2 = testdir.getitems("""
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
pass pass
class TestClass: class TestClass:
def test_func1(self, something): def test_func1(self, something):
@ -737,7 +782,10 @@ class TestRequestCachedSetup:
reprec = testdir.inline_runsource(""" reprec = testdir.inline_runsource("""
mysetup = ["hello",].pop mysetup = ["hello",].pop
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
return request.cached_setup(mysetup, scope="module") return request.cached_setup(mysetup, scope="module")
def test_func1(something): def test_func1(something):
@ -752,7 +800,9 @@ class TestRequestCachedSetup:
reprec = testdir.inline_runsource(""" reprec = testdir.inline_runsource("""
mysetup = ["hello", "hello2", "hello3"].pop mysetup = ["hello", "hello2", "hello3"].pop
def pytest_funcarg__something(request): import pytest
@pytest.fixture
def something(request):
return request.cached_setup(mysetup, scope="class") return request.cached_setup(mysetup, scope="class")
def test_func1(something): def test_func1(something):
assert something == "hello3" assert something == "hello3"
@ -802,9 +852,13 @@ class TestRequestCachedSetup:
def test_request_cached_setup_two_args(self, testdir): def test_request_cached_setup_two_args(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
return request.cached_setup(lambda: 42) return request.cached_setup(lambda: 42)
def pytest_funcarg__arg2(request): @pytest.fixture
def arg2(request):
return request.cached_setup(lambda: 17) return request.cached_setup(lambda: 17)
def test_two_different_setups(arg1, arg2): def test_two_different_setups(arg1, arg2):
assert arg1 != arg2 assert arg1 != arg2
@ -816,10 +870,14 @@ class TestRequestCachedSetup:
def test_request_cached_setup_getfixturevalue(self, testdir): def test_request_cached_setup_getfixturevalue(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
arg1 = request.getfixturevalue("arg2") arg1 = request.getfixturevalue("arg2")
return request.cached_setup(lambda: arg1 + 1) return request.cached_setup(lambda: arg1 + 1)
def pytest_funcarg__arg2(request): @pytest.fixture
def arg2(request):
return request.cached_setup(lambda: 10) return request.cached_setup(lambda: 10)
def test_two_funcarg(arg1): def test_two_funcarg(arg1):
assert arg1 == 11 assert arg1 == 11
@ -831,8 +889,10 @@ class TestRequestCachedSetup:
def test_request_cached_setup_functional(self, testdir): def test_request_cached_setup_functional(self, testdir):
testdir.makepyfile(test_0=""" testdir.makepyfile(test_0="""
import pytest
l = [] l = []
def pytest_funcarg__something(request): @pytest.fixture
def something(request):
val = request.cached_setup(fsetup, fteardown) val = request.cached_setup(fsetup, fteardown)
return val return val
def fsetup(mycache=[1]): def fsetup(mycache=[1]):
@ -858,7 +918,10 @@ class TestRequestCachedSetup:
def test_issue117_sessionscopeteardown(self, testdir): def test_issue117_sessionscopeteardown(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__app(request): import pytest
@pytest.fixture
def app(request):
app = request.cached_setup( app = request.cached_setup(
scope='session', scope='session',
setup=lambda: 0, setup=lambda: 0,
@ -1119,16 +1182,23 @@ class TestFixtureUsages:
class TestFixtureManagerParseFactories: class TestFixtureManagerParseFactories:
def pytest_funcarg__testdir(self, request):
@pytest.fixture
def testdir(self, request):
testdir = request.getfixturevalue("testdir") testdir = request.getfixturevalue("testdir")
testdir.makeconftest(""" testdir.makeconftest("""
def pytest_funcarg__hello(request): import pytest
@pytest.fixture
def hello(request):
return "conftest" return "conftest"
def pytest_funcarg__fm(request): @pytest.fixture
def fm(request):
return request._fixturemanager return request._fixturemanager
def pytest_funcarg__item(request): @pytest.fixture
def item(request):
return request._pyfuncitem return request._pyfuncitem
""") """)
return testdir return testdir
@ -1154,17 +1224,21 @@ class TestFixtureManagerParseFactories:
faclist = fm.getfixturedefs(name, item.nodeid) faclist = fm.getfixturedefs(name, item.nodeid)
assert len(faclist) == 1 assert len(faclist) == 1
fac = faclist[0] fac = faclist[0]
assert fac.func.__name__ == "pytest_funcarg__" + name assert fac.func.__name__ == name
""") """)
reprec = testdir.inline_run("-s") reprec = testdir.inline_run("-s")
reprec.assertoutcome(passed=1) reprec.assertoutcome(passed=1)
def test_parsefactories_conftest_and_module_and_class(self, testdir): def test_parsefactories_conftest_and_module_and_class(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__hello(request): import pytest
@pytest.fixture
def hello(request):
return "module" return "module"
class TestClass: class TestClass:
def pytest_funcarg__hello(self, request): @pytest.fixture
def hello(self, request):
return "class" return "class"
def test_hello(self, item, fm): def test_hello(self, item, fm):
faclist = fm.getfixturedefs("hello", item.nodeid) faclist = fm.getfixturedefs("hello", item.nodeid)
@ -1212,7 +1286,9 @@ class TestFixtureManagerParseFactories:
class TestAutouseDiscovery: class TestAutouseDiscovery:
def pytest_funcarg__testdir(self, testdir):
@pytest.fixture
def testdir(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
import pytest import pytest
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
@ -1226,10 +1302,12 @@ class TestAutouseDiscovery:
def perfunction2(arg1): def perfunction2(arg1):
pass pass
def pytest_funcarg__fm(request): @pytest.fixture
def fm(request):
return request._fixturemanager return request._fixturemanager
def pytest_funcarg__item(request): @pytest.fixture
def item(request):
return request._pyfuncitem return request._pyfuncitem
""") """)
return testdir return testdir
@ -1773,17 +1851,19 @@ class TestFixtureMarker:
def test_scope_module_and_finalizer(self, testdir): def test_scope_module_and_finalizer(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
import pytest import pytest
finalized = [] finalized_list = []
created = [] created_list = []
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def arg(request): def arg(request):
created.append(1) created_list.append(1)
assert request.scope == "module" assert request.scope == "module"
request.addfinalizer(lambda: finalized.append(1)) request.addfinalizer(lambda: finalized_list.append(1))
def pytest_funcarg__created(request): @pytest.fixture
return len(created) def created(request):
def pytest_funcarg__finalized(request): return len(created_list)
return len(finalized) @pytest.fixture
def finalized(request):
return len(finalized_list)
""") """)
testdir.makepyfile( testdir.makepyfile(
test_mod1=""" test_mod1="""

View File

@ -15,7 +15,9 @@ class TestOEJSKITSpecials:
return self.fspath, 3, "xyz" return self.fspath, 3, "xyz"
""") """)
modcol = testdir.getmodulecol(""" modcol = testdir.getmodulecol("""
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
return 42 return 42
class MyClass: class MyClass:
pass pass
@ -43,7 +45,8 @@ class TestOEJSKITSpecials:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def hello(): def hello():
pass pass
def pytest_funcarg__arg1(request): @pytest.fixture
def arg1(request):
return 42 return 42
class MyClass: class MyClass:
pass pass

View File

@ -448,13 +448,13 @@ class TestMetafunc:
def test_parametrize_functional(self, testdir): def test_parametrize_functional(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
import pytest
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
metafunc.parametrize('x', [1,2], indirect=True) metafunc.parametrize('x', [1,2], indirect=True)
metafunc.parametrize('y', [2]) metafunc.parametrize('y', [2])
def pytest_funcarg__x(request): @pytest.fixture
def x(request):
return request.param * 10 return request.param * 10
#def pytest_funcarg__y(request):
# return request.param
def test_simple(x,y): def test_simple(x,y):
assert x in (10,20) assert x in (10,20)
@ -578,7 +578,8 @@ class TestMetafuncFunctional:
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
metafunc.addcall(param=metafunc) metafunc.addcall(param=metafunc)
def pytest_funcarg__metafunc(request): @pytest.fixture
def metafunc(request):
assert request._pyfuncitem._genid == "0" assert request._pyfuncitem._genid == "0"
return request.param return request.param
@ -630,7 +631,9 @@ class TestMetafuncFunctional:
metafunc.addcall(param=10) metafunc.addcall(param=10)
metafunc.addcall(param=20) metafunc.addcall(param=20)
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
return request.param return request.param
def test_func1(arg1): def test_func1(arg1):
@ -669,9 +672,12 @@ class TestMetafuncFunctional:
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
metafunc.addcall(param=(1,1), id="hello") metafunc.addcall(param=(1,1), id="hello")
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
return request.param[0] return request.param[0]
def pytest_funcarg__arg2(request): @pytest.fixture
def arg2(request):
return request.param[1] return request.param[1]
class TestClass: class TestClass:
@ -755,11 +761,14 @@ class TestMetafuncFunctional:
metafunc.parametrize("arg1", [1], indirect=True) metafunc.parametrize("arg1", [1], indirect=True)
metafunc.parametrize("arg2", [10], indirect=True) metafunc.parametrize("arg2", [10], indirect=True)
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
x = request.getfixturevalue("arg2") x = request.getfixturevalue("arg2")
return x + request.param return x + request.param
def pytest_funcarg__arg2(request): @pytest.fixture
def arg2(request):
return request.param return request.param
def test_func1(arg1, arg2): def test_func1(arg1, arg2):
@ -777,10 +786,13 @@ class TestMetafuncFunctional:
assert "arg1" in metafunc.fixturenames assert "arg1" in metafunc.fixturenames
metafunc.parametrize("arg1", [1], indirect=True) metafunc.parametrize("arg1", [1], indirect=True)
def pytest_funcarg__arg1(request): import pytest
@pytest.fixture
def arg1(request):
return request.param return request.param
def pytest_funcarg__arg2(request, arg1): @pytest.fixture
def arg2(request, arg1):
return 10 * arg1 return 10 * arg1
def test_func(arg2): def test_func(arg2):
@ -870,7 +882,8 @@ class TestMetafuncFunctional:
if "arg" in metafunc.funcargnames: if "arg" in metafunc.funcargnames:
metafunc.parametrize("arg", [1,2], indirect=True, metafunc.parametrize("arg", [1,2], indirect=True,
scope=%r) scope=%r)
def pytest_funcarg__arg(request): @pytest.fixture
def arg(request):
l.append(request.param) l.append(request.param)
return request.param return request.param
def test_hello(arg): def test_hello(arg):

View File

@ -30,17 +30,20 @@ class TestBinReprIntegration:
def test_pytest_assertrepr_compare_called(self, testdir): def test_pytest_assertrepr_compare_called(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
import pytest
l = [] l = []
def pytest_assertrepr_compare(op, left, right): def pytest_assertrepr_compare(op, left, right):
l.append((op, left, right)) l.append((op, left, right))
def pytest_funcarg__l(request):
@pytest.fixture
def list(request):
return l return l
""") """)
testdir.makepyfile(""" testdir.makepyfile("""
def test_hello(): def test_hello():
assert 0 == 1 assert 0 == 1
def test_check(l): def test_check(list):
assert l == [("==", 0, 1)] assert list == [("==", 0, 1)]
""") """)
result = testdir.runpytest("-v") result = testdir.runpytest("-v")
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([

View File

@ -119,7 +119,10 @@ class TestPython:
def test_setup_error(self, testdir): def test_setup_error(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__arg(request): import pytest
@pytest.fixture
def arg(request):
raise ValueError() raise ValueError()
def test_function(arg): def test_function(arg):
pass pass
@ -131,7 +134,7 @@ class TestPython:
tnode = node.find_first_by_tag("testcase") tnode = node.find_first_by_tag("testcase")
tnode.assert_attr( tnode.assert_attr(
file="test_setup_error.py", file="test_setup_error.py",
line="2", line="5",
classname="test_setup_error", classname="test_setup_error",
name="test_function") name="test_function")
fnode = tnode.find_first_by_tag("error") fnode = tnode.find_first_by_tag("error")
@ -444,7 +447,10 @@ class TestPython:
def test_setup_error_captures_stdout(self, testdir): def test_setup_error_captures_stdout(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__arg(request): import pytest
@pytest.fixture
def arg(request):
print('hello-stdout') print('hello-stdout')
raise ValueError() raise ValueError()
def test_function(arg): def test_function(arg):
@ -459,7 +465,10 @@ class TestPython:
def test_setup_error_captures_stderr(self, testdir): def test_setup_error_captures_stderr(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
import sys import sys
def pytest_funcarg__arg(request): import pytest
@pytest.fixture
def arg(request):
sys.stderr.write('hello-stderr') sys.stderr.write('hello-stderr')
raise ValueError() raise ValueError()
def test_function(arg): def test_function(arg):

View File

@ -481,7 +481,8 @@ class TestFunctional:
def test_mark_dynamically_in_funcarg(self, testdir): def test_mark_dynamically_in_funcarg(self, testdir):
testdir.makeconftest(""" testdir.makeconftest("""
import pytest import pytest
def pytest_funcarg__arg(request): @pytest.fixture
def arg(request):
request.applymarker(pytest.mark.hello) request.applymarker(pytest.mark.hello)
def pytest_terminal_summary(terminalreporter): def pytest_terminal_summary(terminalreporter):
l = terminalreporter.stats['passed'] l = terminalreporter.stats['passed']

View File

@ -3,10 +3,11 @@ import sys
import textwrap import textwrap
import pytest import pytest
from _pytest.monkeypatch import monkeypatch as MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
def pytest_funcarg__mp(request): @pytest.fixture
def mp(request):
cwd = os.getcwd() cwd = os.getcwd()
sys_path = list(sys.path) sys_path = list(sys.path)
@ -205,7 +206,7 @@ def test_setenv_prepend():
def test_monkeypatch_plugin(testdir): def test_monkeypatch_plugin(testdir):
reprec = testdir.inline_runsource(""" reprec = testdir.inline_runsource("""
def test_method(monkeypatch): def test_method(monkeypatch):
assert monkeypatch.__class__.__name__ == "monkeypatch" assert monkeypatch.__class__.__name__ == "MonkeyPatch"
""") """)
res = reprec.countoutcomes() res = reprec.countoutcomes()
assert tuple(res) == (1, 0, 0), res assert tuple(res) == (1, 0, 0), res

View File

@ -1,6 +1,7 @@
import sys import sys
import _pytest._code import _pytest._code
import pytest
def runpdb_and_get_report(testdir, source): def runpdb_and_get_report(testdir, source):
@ -12,7 +13,9 @@ def runpdb_and_get_report(testdir, source):
class TestPDB: class TestPDB:
def pytest_funcarg__pdblist(self, request):
@pytest.fixture
def pdblist(self, request):
monkeypatch = request.getfixturevalue("monkeypatch") monkeypatch = request.getfixturevalue("monkeypatch")
pdblist = [] pdblist = []
def mypdb(*args): def mypdb(*args):

View File

@ -399,13 +399,15 @@ def test_callinfo():
@pytest.mark.xfail @pytest.mark.xfail
def test_runtest_in_module_ordering(testdir): def test_runtest_in_module_ordering(testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile("""
import pytest
def pytest_runtest_setup(item): # runs after class-level! def pytest_runtest_setup(item): # runs after class-level!
item.function.mylist.append("module") item.function.mylist.append("module")
class TestClass: class TestClass:
def pytest_runtest_setup(self, item): def pytest_runtest_setup(self, item):
assert not hasattr(item.function, 'mylist') assert not hasattr(item.function, 'mylist')
item.function.mylist = ['class'] item.function.mylist = ['class']
def pytest_funcarg__mylist(self, request): @pytest.fixture
def mylist(self, request):
return request.function.mylist return request.function.mylist
def pytest_runtest_call(self, item, __multicall__): def pytest_runtest_call(self, item, __multicall__):
try: try:

View File

@ -234,7 +234,8 @@ def test_setup_funcarg_setup_when_outer_scope_fails(testdir):
import pytest import pytest
def setup_module(mod): def setup_module(mod):
raise ValueError(42) raise ValueError(42)
def pytest_funcarg__hello(request): @pytest.fixture
def hello(request):
raise ValueError("xyz43") raise ValueError("xyz43")
def test_function1(hello): def test_function1(hello):
pass pass

View File

@ -309,7 +309,8 @@ class TestXFail:
def test_dynamic_xfail_no_run(self, testdir): def test_dynamic_xfail_no_run(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
import pytest import pytest
def pytest_funcarg__arg(request): @pytest.fixture
def arg(request):
request.applymarker(pytest.mark.xfail(run=False)) request.applymarker(pytest.mark.xfail(run=False))
def test_this(arg): def test_this(arg):
assert 0 assert 0
@ -323,7 +324,8 @@ class TestXFail:
def test_dynamic_xfail_set_during_funcarg_setup(self, testdir): def test_dynamic_xfail_set_during_funcarg_setup(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
import pytest import pytest
def pytest_funcarg__arg(request): @pytest.fixture
def arg(request):
request.applymarker(pytest.mark.xfail) request.applymarker(pytest.mark.xfail)
def test_this2(arg): def test_this2(arg):
assert 0 assert 0

View File

@ -600,7 +600,10 @@ def test_getreportopt():
def test_terminalreporter_reportopt_addopts(testdir): def test_terminalreporter_reportopt_addopts(testdir):
testdir.makeini("[pytest]\naddopts=-rs") testdir.makeini("[pytest]\naddopts=-rs")
testdir.makepyfile(""" testdir.makepyfile("""
def pytest_funcarg__tr(request): import pytest
@pytest.fixture
def tr(request):
tr = request.config.pluginmanager.getplugin("terminalreporter") tr = request.config.pluginmanager.getplugin("terminalreporter")
return tr return tr
def test_opt(tr): def test_opt(tr):
@ -614,7 +617,10 @@ def test_terminalreporter_reportopt_addopts(testdir):
def test_tbstyle_short(testdir): def test_tbstyle_short(testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
def pytest_funcarg__arg(request): import pytest
@pytest.fixture
def arg(request):
return 42 return 42
def test_opt(arg): def test_opt(arg):
x = 0 x = 0
@ -625,7 +631,7 @@ def test_tbstyle_short(testdir):
assert 'arg = 42' not in s assert 'arg = 42' not in s
assert 'x = 0' not in s assert 'x = 0' not in s
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"*%s:5*" % p.basename, "*%s:8*" % p.basename,
" assert x", " assert x",
"E assert*", "E assert*",
]) ])

View File

@ -265,8 +265,8 @@ def test_testcase_custom_exception_info(testdir, type):
def run(self, result): def run(self, result):
excinfo = pytest.raises(ZeroDivisionError, lambda: 0/0) excinfo = pytest.raises(ZeroDivisionError, lambda: 0/0)
# we fake an incompatible exception info # we fake an incompatible exception info
from _pytest.monkeypatch import monkeypatch from _pytest.monkeypatch import MonkeyPatch
mp = monkeypatch() mp = MonkeyPatch()
def t(*args): def t(*args):
mp.undo() mp.undo()
raise TypeError() raise TypeError()