From 9c9679945e16aeab710da1fc001d0f689deaadc8 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Mon, 25 Mar 2013 10:52:02 +0100 Subject: [PATCH] fix Issue 265 - integrate nose setup/teardown with setupstate as sideeffect teardown is only called if setup doesnt fail --- CHANGELOG | 3 +++ _pytest/nose.py | 4 +++- testing/test_nose.py | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index c04e3f149..005654605 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 2.3.4 and 2.3.5dev ----------------------------------- +- Issue 265 - integrate nose setup/teardown with setupstate + so it doesnt try to teardown if it did not setup + - issue 271 - dont write junitxml on slave nodes - Issue 274 - dont try to show full doctest example diff --git a/_pytest/nose.py b/_pytest/nose.py index 3064af039..d61dc8a03 100644 --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -28,8 +28,10 @@ def pytest_runtest_setup(item): if not call_optional(item.obj, 'setup'): # call module level setup if there is no object level one call_optional(item.parent.obj, 'setup') + #XXX this implies we only call teardown when setup worked + item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item) -def pytest_runtest_teardown(item): +def teardown_nose(item): if is_potential_nosetest(item): if not call_optional(item.obj, 'teardown'): call_optional(item.parent.obj, 'teardown') diff --git a/testing/test_nose.py b/testing/test_nose.py index 487b1bbb0..cdebca8dd 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -304,4 +304,27 @@ def test_apiwrapper_problem_issue260(testdir): result = testdir.runpytest() result.stdout.fnmatch_lines("*1 passed*") +def test_setup_teardown_linking_issue265(testdir): + # we accidnetially didnt integrate nose setupstate with normal setupstate + # this test ensures that won't happen again + testdir.makepyfile(''' + import pytest + class TestGeneric(object): + def test_nothing(self): + """Tests the API of the implementation (for generic and specialized).""" + + @pytest.mark.skipif("True", reason="Skip tests to check if teardown is skipped as well.") + class TestSkipTeardown(TestGeneric): + + def setup(self): + """Sets up my specialized implementation for $COOL_PLATFORM.""" + raise Exception("should not call setup for skipped tests") + + def teardown(self): + """Undoes the setup.""" + raise Exception("should not call teardown for skipped tests") + ''') + + result = testdir.runpytest() + result.stdout.fnmatch_lines("*1 skipped*")