From 162c3689c60471a3e19110e8b7f27720a9185891 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 7 Feb 2013 17:53:13 +0100 Subject: [PATCH] fix issue 260 - don't use nose specials on plain unittest cases --- CHANGELOG | 2 ++ _pytest/nose.py | 14 ++++++++++++-- testing/test_nose.py | 25 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9d8202e63..1c9c9a2c3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -21,6 +21,8 @@ Changes between 2.3.4 and 2.3.5dev - ensure OutcomeExceptions like skip/fail have initialized exception attributes +- fix issue 260 - don't use nose specials on plain unittest cases + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff --git a/_pytest/nose.py b/_pytest/nose.py index d82247c2b..3064af039 100644 --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -3,6 +3,8 @@ import pytest, py import inspect import sys +from _pytest import unittest + def pytest_runtest_makereport(__multicall__, item, call): SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None) @@ -15,7 +17,7 @@ def pytest_runtest_makereport(__multicall__, item, call): @pytest.mark.trylast def pytest_runtest_setup(item): - if isinstance(item, (pytest.Function)): + if is_potential_nosetest(item): if isinstance(item.parent, pytest.Generator): gen = item.parent if not hasattr(gen, '_nosegensetup'): @@ -28,7 +30,7 @@ def pytest_runtest_setup(item): call_optional(item.parent.obj, 'setup') def pytest_runtest_teardown(item): - if isinstance(item, pytest.Function): + if is_potential_nosetest(item): if not call_optional(item.obj, 'teardown'): call_optional(item.parent.obj, 'teardown') #if hasattr(item.parent, '_nosegensetup'): @@ -39,6 +41,14 @@ def pytest_make_collect_report(collector): if isinstance(collector, pytest.Generator): call_optional(collector.obj, 'setup') + +def is_potential_nosetest(item): + # extra check needed since we do not do nose style setup/teardown + # on direct unittest style classes + return isinstance(item, pytest.Function) and \ + not isinstance(item, unittest.TestCaseFunction) + + def call_optional(obj, name): method = getattr(obj, name, None) isfixture = hasattr(method, "_pytestfixturefunction") diff --git a/testing/test_nose.py b/testing/test_nose.py index 99d10f9c3..487b1bbb0 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -280,3 +280,28 @@ def test_nose_setup_ordering(testdir): result.stdout.fnmatch_lines([ "*1 passed*", ]) + + +def test_apiwrapper_problem_issue260(testdir): + # this would end up trying a call a optional teardown on the class + # for plain unittests we dont want nose behaviour + testdir.makepyfile(""" + import unittest + class TestCase(unittest.TestCase): + def setup(self): + #should not be called in unittest testcases + assert 0, 'setup' + def teardown(self): + #should not be called in unittest testcases + assert 0, 'teardown' + def setUp(self): + print('setup') + def tearDown(self): + print('teardown') + def test_fun(self): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines("*1 passed*") + +