fix issue217 - to support @mock.patch with pytest funcarg-fixtures, also split out python integration tests into python/integration.py and fix nose/mark tests
This commit is contained in:
parent
f203401964
commit
dba2a8bc64
|
@ -24,6 +24,9 @@ Changes between 2.3.2 and 2.3.3.dev
|
|||
- in tracebacks *,** arg values are now shown next to normal arguments
|
||||
(thanks Manuel Jacob)
|
||||
|
||||
- fix issue217 - support mock.patch with pytest's fixtures - note that
|
||||
you need either mock-1.0.1 or the python3.3 builtin unittest.mock.
|
||||
|
||||
Changes between 2.3.1 and 2.3.2
|
||||
-----------------------------------
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#
|
||||
__version__ = '2.3.3.dev3'
|
||||
__version__ = '2.3.3.dev4'
|
||||
|
|
|
@ -1659,8 +1659,14 @@ class FixtureDef:
|
|||
def getfuncargnames(function, startindex=None):
|
||||
# XXX merge with main.py's varnames
|
||||
#assert not inspect.isclass(function)
|
||||
realfunction = function
|
||||
while hasattr(realfunction, "__wrapped__"):
|
||||
realfunction = realfunction.__wrapped__
|
||||
if startindex is None:
|
||||
startindex = inspect.ismethod(function) and 1 or 0
|
||||
if realfunction != function:
|
||||
startindex += len(getattr(function, "patchings", []))
|
||||
function = realfunction
|
||||
argnames = inspect.getargs(py.code.getrawcode(function))[0]
|
||||
defaults = getattr(function, 'func_defaults',
|
||||
getattr(function, '__defaults__', None)) or ()
|
||||
|
|
2
setup.py
2
setup.py
|
@ -24,7 +24,7 @@ def main():
|
|||
name='pytest',
|
||||
description='py.test: simple powerful testing with Python',
|
||||
long_description = long_description,
|
||||
version='2.3.3.dev3',
|
||||
version='2.3.3.dev4',
|
||||
url='http://pytest.org',
|
||||
license='MIT license',
|
||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||
|
|
|
@ -541,59 +541,6 @@ class TestRequestCachedSetup:
|
|||
"*ZeroDivisionError*",
|
||||
])
|
||||
|
||||
class TestOEJSKITSpecials:
|
||||
def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
def pytest_pycollect_makeitem(collector, name, obj):
|
||||
if name == "MyClass":
|
||||
return MyCollector(name, parent=collector)
|
||||
class MyCollector(pytest.Collector):
|
||||
def reportinfo(self):
|
||||
return self.fspath, 3, "xyz"
|
||||
""")
|
||||
modcol = testdir.getmodulecol("""
|
||||
def pytest_funcarg__arg1(request):
|
||||
return 42
|
||||
class MyClass:
|
||||
pass
|
||||
""")
|
||||
# this hook finds funcarg factories
|
||||
rep = modcol.ihook.pytest_make_collect_report(collector=modcol)
|
||||
clscol = rep.result[0]
|
||||
clscol.obj = lambda arg1: None
|
||||
clscol.funcargs = {}
|
||||
funcargs.fillfixtures(clscol)
|
||||
assert clscol.funcargs['arg1'] == 42
|
||||
|
||||
def test_autouse_fixture(self, testdir): # rough jstests usage
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
def pytest_pycollect_makeitem(collector, name, obj):
|
||||
if name == "MyClass":
|
||||
return MyCollector(name, parent=collector)
|
||||
class MyCollector(pytest.Collector):
|
||||
def reportinfo(self):
|
||||
return self.fspath, 3, "xyz"
|
||||
""")
|
||||
modcol = testdir.getmodulecol("""
|
||||
import pytest
|
||||
@pytest.fixture(autouse=True)
|
||||
def hello():
|
||||
pass
|
||||
def pytest_funcarg__arg1(request):
|
||||
return 42
|
||||
class MyClass:
|
||||
pass
|
||||
""")
|
||||
# this hook finds funcarg factories
|
||||
rep = modcol.ihook.pytest_make_collect_report(collector=modcol)
|
||||
clscol = rep.result[0]
|
||||
clscol.obj = lambda: None
|
||||
clscol.funcargs = {}
|
||||
funcargs.fillfixtures(clscol)
|
||||
assert not clscol.funcargs
|
||||
|
||||
class TestFixtureUsages:
|
||||
def test_noargfixturedec(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
import pytest, py, sys
|
||||
|
||||
class TestOEJSKITSpecials:
|
||||
def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
def pytest_pycollect_makeitem(collector, name, obj):
|
||||
if name == "MyClass":
|
||||
return MyCollector(name, parent=collector)
|
||||
class MyCollector(pytest.Collector):
|
||||
def reportinfo(self):
|
||||
return self.fspath, 3, "xyz"
|
||||
""")
|
||||
modcol = testdir.getmodulecol("""
|
||||
def pytest_funcarg__arg1(request):
|
||||
return 42
|
||||
class MyClass:
|
||||
pass
|
||||
""")
|
||||
# this hook finds funcarg factories
|
||||
rep = modcol.ihook.pytest_make_collect_report(collector=modcol)
|
||||
clscol = rep.result[0]
|
||||
clscol.obj = lambda arg1: None
|
||||
clscol.funcargs = {}
|
||||
pytest._fillfuncargs(clscol)
|
||||
assert clscol.funcargs['arg1'] == 42
|
||||
|
||||
def test_autouse_fixture(self, testdir): # rough jstests usage
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
def pytest_pycollect_makeitem(collector, name, obj):
|
||||
if name == "MyClass":
|
||||
return MyCollector(name, parent=collector)
|
||||
class MyCollector(pytest.Collector):
|
||||
def reportinfo(self):
|
||||
return self.fspath, 3, "xyz"
|
||||
""")
|
||||
modcol = testdir.getmodulecol("""
|
||||
import pytest
|
||||
@pytest.fixture(autouse=True)
|
||||
def hello():
|
||||
pass
|
||||
def pytest_funcarg__arg1(request):
|
||||
return 42
|
||||
class MyClass:
|
||||
pass
|
||||
""")
|
||||
# this hook finds funcarg factories
|
||||
rep = modcol.ihook.pytest_make_collect_report(collector=modcol)
|
||||
clscol = rep.result[0]
|
||||
clscol.obj = lambda: None
|
||||
clscol.funcargs = {}
|
||||
pytest._fillfuncargs(clscol)
|
||||
assert not clscol.funcargs
|
||||
|
||||
|
||||
class TestMockDecoration:
|
||||
def test_wrapped_getfuncargnames(self):
|
||||
from _pytest.python import getfuncargnames
|
||||
def wrap(f):
|
||||
def func():
|
||||
pass
|
||||
func.__wrapped__ = f
|
||||
return func
|
||||
@wrap
|
||||
def f(x):
|
||||
pass
|
||||
l = getfuncargnames(f)
|
||||
assert l == ("x",)
|
||||
|
||||
def test_wrapped_getfuncargnames_patching(self):
|
||||
from _pytest.python import getfuncargnames
|
||||
def wrap(f):
|
||||
def func():
|
||||
pass
|
||||
func.__wrapped__ = f
|
||||
func.patchings = ["qwe"]
|
||||
return func
|
||||
@wrap
|
||||
def f(x, y, z):
|
||||
pass
|
||||
l = getfuncargnames(f)
|
||||
assert l == ("y", "z")
|
||||
|
||||
def test_unittest_mock(self, testdir):
|
||||
pytest.importorskip("unittest.mock")
|
||||
testdir.makepyfile("""
|
||||
import unittest.mock
|
||||
class T(unittest.TestCase):
|
||||
@unittest.mock.patch("os.path.abspath")
|
||||
def test_hello(self, abspath):
|
||||
import os
|
||||
os.path.abspath("hello")
|
||||
abspath.assert_any_call("hello")
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_mock(self, testdir):
|
||||
pytest.importorskip("mock", "1.0.1")
|
||||
testdir.makepyfile("""
|
||||
import os
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
class T(unittest.TestCase):
|
||||
@mock.patch("os.path.abspath")
|
||||
def test_hello(self, abspath):
|
||||
os.path.abspath("hello")
|
||||
abspath.assert_any_call("hello")
|
||||
@mock.patch("os.path.abspath")
|
||||
@mock.patch("os.path.normpath")
|
||||
def test_someting(normpath, abspath, tmpdir):
|
||||
abspath.return_value = "this"
|
||||
os.path.normpath(os.path.abspath("hello"))
|
||||
normpath.assert_any_call("this")
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=2)
|
|
@ -253,7 +253,7 @@ class TestFunctional:
|
|||
""")
|
||||
items, rec = testdir.inline_genitems(p)
|
||||
for item in items:
|
||||
print item, item.keywords
|
||||
print (item, item.keywords)
|
||||
assert 'a' in item.keywords
|
||||
|
||||
def test_mark_with_wrong_marker(self, testdir):
|
||||
|
|
|
@ -103,21 +103,13 @@ def test_nose_setup_func_failure_2(testdir):
|
|||
my_teardown = 2
|
||||
|
||||
def test_hello():
|
||||
print (l)
|
||||
assert l == [1]
|
||||
|
||||
def test_world():
|
||||
print (l)
|
||||
assert l == [1,2]
|
||||
assert l == []
|
||||
|
||||
test_hello.setup = my_setup
|
||||
test_hello.teardown = my_teardown
|
||||
""")
|
||||
result = testdir.runpytest(p, '-p', 'nose')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*TypeError: 'int' object is not callable*"
|
||||
])
|
||||
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_nose_setup_partial(testdir):
|
||||
py.test.importorskip("functools")
|
||||
|
|
Loading…
Reference in New Issue