diff --git a/CHANGELOG b/CHANGELOG index a25705ad4..2262a33f9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ Unreleased - fix issue287 by running all finalizers but saving the exception from the last failing finalizer and re-raising it so teardown will still have failed. +- fix ordering when mock.patch or other standard decorator-wrappings + are used with test methods. This fixues issue346. Thanks to + Ronny Pfannschmidt and Donald Stufft for helping to isolate it. - fix issue384 by removing the trial support code since the unittest compat enhancements allow diff --git a/_pytest/main.py b/_pytest/main.py index 372a8019d..48084bab9 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -697,11 +697,4 @@ class Session(FSCollector): yield x node.ihook.pytest_collectreport(report=rep) -def getfslineno(obj): - # xxx let decorators etc specify a sane ordering - if hasattr(obj, 'place_as'): - obj = obj.place_as - fslineno = py.code.getfslineno(obj) - assert isinstance(fslineno[1], int), obj - return fslineno diff --git a/_pytest/python.py b/_pytest/python.py index c09fc6f36..d10100a99 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -3,7 +3,6 @@ import py import inspect import sys import pytest -from _pytest.main import getfslineno from _pytest.mark import MarkDecorator from _pytest.monkeypatch import monkeypatch from py._code.code import TerminalRepr @@ -15,6 +14,16 @@ NoneType = type(None) callable = py.builtin.callable +def getfslineno(obj): + # xxx let decorators etc specify a sane ordering + while hasattr(obj, "__wrapped__"): + obj = obj.__wrapped__ + if hasattr(obj, 'place_as'): + obj = obj.place_as + fslineno = py.code.getfslineno(obj) + assert isinstance(fslineno[1], int), obj + return fslineno + def getimfunc(func): try: return func.__func__ diff --git a/extra/get_issues.py b/extra/get_issues.py index 5e6ab9a68..6045d49c7 100644 --- a/extra/get_issues.py +++ b/extra/get_issues.py @@ -66,7 +66,8 @@ def report(issues): if __name__ == "__main__": import argparse parser = argparse.ArgumentParser("process bitbucket issues") - parser.add_argument("--refresh", help="invalidate cache, refresh issues") + parser.add_argument("--refresh", action="store_true", + help="invalidate cache, refresh issues") parser.add_argument("--cache", action="store", default="issues.json", help="cache file") args = parser.parse_args() diff --git a/testing/python/integration.py b/testing/python/integration.py index 00e70df83..60002b83f 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -1,5 +1,6 @@ import pytest from _pytest import runner +from _pytest import python class TestOEJSKITSpecials: def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage @@ -55,6 +56,20 @@ class TestOEJSKITSpecials: assert not clscol.funcargs +def test_wrapped_getfslineno(): + def func(): + pass + def wrap(f): + func.__wrapped__ = f + func.patchings = ["qwe"] + return func + @wrap + def wrapped_func(x, y, z): + pass + fs, lineno = python.getfslineno(wrapped_func) + fs2, lineno2 = python.getfslineno(wrap) + assert lineno > lineno2, "getfslineno does not unwrap correctly" + class TestMockDecoration: def test_wrapped_getfuncargnames(self): from _pytest.python import getfuncargnames @@ -119,6 +134,28 @@ class TestMockDecoration: reprec = testdir.inline_run() reprec.assertoutcome(passed=2) + def test_mock_sorting(self, testdir): + pytest.importorskip("mock", "1.0.1") + testdir.makepyfile(""" + import os + import mock + + @mock.patch("os.path.abspath") + def test_one(abspath): + pass + @mock.patch("os.path.abspath") + def test_two(abspath): + pass + @mock.patch("os.path.abspath") + def test_three(abspath): + pass + """) + reprec = testdir.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"] + class TestReRunTests: def test_rerun(self, testdir): diff --git a/testing/test_genscript.py b/testing/test_genscript.py index eb2e634b5..f790d546a 100644 --- a/testing/test_genscript.py +++ b/testing/test_genscript.py @@ -35,14 +35,3 @@ def test_gen(testdir, anypython, standalone): result = standalone.run(anypython, testdir, p) assert result.ret != 0 -def test_rundist(testdir, pytestconfig, standalone): - pytestconfig.pluginmanager.skipifmissing("xdist") - testdir.makepyfile(""" - def test_one(): - pass - """) - result = standalone.run(sys.executable, testdir, '-n', '3') - assert result.ret == 0 - result.stdout.fnmatch_lines([ - "*1 passed*", - ]) diff --git a/tox.ini b/tox.ini index 2719a9b70..e676b71b7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,11 @@ [tox] distshare={homedir}/.tox/distshare -envlist=flakes,py25,py26,py27,pypy,py27-nobyte,py32,py33,py27-xdist,trial +envlist=flakes,py25,py26,py27,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,trial [testenv] changedir=testing commands= py.test --lsof -rfsxX --junitxml={envlogdir}/junit-{envname}.xml [] deps= - pexpect nose [testenv:genscript] @@ -33,6 +32,28 @@ commands= py.test -n3 -rfsxX \ --junitxml={envlogdir}/junit-{envname}.xml testing +[testenv:py33-xdist] +changedir=. +basepython=python3.3 +deps={[testenv:py27-xdist]deps} +commands= + py.test -n3 -rfsxX \ + --junitxml={envlogdir}/junit-{envname}.xml testing + +[testenv:py27-pexpect] +changedir=testing +basepython=python2.7 +deps=pexpect +commands= + py.test -rfsxX test_pdb.py test_terminal.py test_unittest.py + +[testenv:py33-pexpect] +changedir=testing +basepython=python2.7 +deps={[testenv:py27-pexpect]deps} +commands= + py.test -rfsxX test_pdb.py test_terminal.py test_unittest.py + [testenv:py27-nobyte] changedir=. basepython=python2.7 @@ -47,7 +68,6 @@ commands= [testenv:trial] changedir=. deps=twisted - pexpect commands= py.test -rsxf \ --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing/test_unittest.py}