From b18ab6e03b86cd4f2abb952bf317ba12c1d990da Mon Sep 17 00:00:00 2001 From: holger krekel Date: Wed, 27 Jan 2010 12:09:30 +0100 Subject: [PATCH] fix issue78 - now python-level teardown functions are now called even if the setup failed. Important detail: if the setup raises a Skipped exception, teardown will not be called. This helps to avoid breaking setup_module/class that performs a skip - it would otherwise internally be considered as a "successful" setup in order to have teardown called later. I guess it also makes sense to treat Skip specially because it is unlikely a teardown should be called if a Skip was raised on setup. In any case, failing setups and teardowns will be reported separately. --HG-- branch : trunk --- CHANGELOG | 3 ++ py/_plugin/pytest_runner.py | 6 +++- testing/plugin/test_pytest_runner_xunit.py | 35 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 31fa5f0d8..1f22b3b89 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 1.2.1 and 1.2.0 ===================================== +- fix issue78: always call python-level teardown functions even if the + according setup failed - but make sure that setup is called repeatedly + and no teardown if the setup raises a Skipped (as sone by py.test.skip()). - fix issue63: assume <40 columns to be a bogus terminal width, default to 80 - update apipkg.py to fix an issue where recursive imports might unnecessarily break importing diff --git a/py/_plugin/pytest_runner.py b/py/_plugin/pytest_runner.py index 6e599cf34..14fa38bb6 100644 --- a/py/_plugin/pytest_runner.py +++ b/py/_plugin/pytest_runner.py @@ -249,5 +249,9 @@ class SetupState(object): break self._pop_and_teardown() for col in needed_collectors[len(self.stack):]: - col.setup() self.stack.append(col) + try: + col.setup() + except Skipped: + self.stack.pop() + raise diff --git a/testing/plugin/test_pytest_runner_xunit.py b/testing/plugin/test_pytest_runner_xunit.py index a610c31b1..f95915a89 100644 --- a/testing/plugin/test_pytest_runner_xunit.py +++ b/testing/plugin/test_pytest_runner_xunit.py @@ -134,3 +134,38 @@ def test_method_setup_uses_fresh_instances(testdir): """) reprec.assertoutcome(passed=2, failed=0) +def test_failing_setup_calls_teardown(testdir): + p = testdir.makepyfile(""" + def setup_module(mod): + raise ValueError(42) + def test_function(): + assert 0 + def teardown_module(mod): + raise ValueError(43) + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*42*", + "*43*", + "*2 error*" + ]) + +def test_setup_that_skips_calledagain_and_no_teardown(testdir): + p = testdir.makepyfile(""" + import py + def setup_module(mod): + py.test.skip("x") + def test_function1(): + pass + def test_function2(): + pass + def teardown_module(mod): + raise ValueError(43) + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*2 skipped*", + ]) + assert "43" not in result.stdout.str() + +