import pytest from _pytest.pytester import Pytester def setup_module(mod): mod.nose = pytest.importorskip("nose") def test_nose_setup(pytester: Pytester) -> None: p = pytester.makepyfile( """ values = [] from nose.tools import with_setup @with_setup(lambda: values.append(1), lambda: values.append(2)) def test_hello(): assert values == [1] def test_world(): assert values == [1,2] test_hello.setup = lambda: values.append(1) test_hello.teardown = lambda: values.append(2) """ ) result = pytester.runpytest( p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" ) result.assert_outcomes(passed=2) def test_setup_func_with_setup_decorator() -> None: from _pytest.nose import call_optional values = [] class A: @pytest.fixture(autouse=True) def f(self): values.append(1) call_optional(A(), "f", "A.f") assert not values def test_setup_func_not_callable() -> None: from _pytest.nose import call_optional class A: f = 1 call_optional(A(), "f", "A.f") def test_nose_setup_func(pytester: Pytester) -> None: p = pytester.makepyfile( """ from nose.tools import with_setup values = [] def my_setup(): a = 1 values.append(a) def my_teardown(): b = 2 values.append(b) @with_setup(my_setup, my_teardown) def test_hello(): print(values) assert values == [1] def test_world(): print(values) assert values == [1,2] """ ) result = pytester.runpytest( p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" ) result.assert_outcomes(passed=2) def test_nose_setup_func_failure(pytester: Pytester) -> None: p = pytester.makepyfile( """ from nose.tools import with_setup values = [] my_setup = lambda x: 1 my_teardown = lambda x: 2 @with_setup(my_setup, my_teardown) def test_hello(): print(values) assert values == [1] def test_world(): print(values) assert values == [1,2] """ ) result = pytester.runpytest( p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" ) result.stdout.fnmatch_lines(["*TypeError: ()*"]) def test_nose_setup_func_failure_2(pytester: Pytester) -> None: pytester.makepyfile( """ values = [] my_setup = 1 my_teardown = 2 def test_hello(): assert values == [] test_hello.setup = my_setup test_hello.teardown = my_teardown """ ) reprec = pytester.inline_run() reprec.assertoutcome(passed=1) def test_nose_setup_partial(pytester: Pytester) -> None: pytest.importorskip("functools") p = pytester.makepyfile( """ from functools import partial values = [] def my_setup(x): a = x values.append(a) def my_teardown(x): b = x values.append(b) my_setup_partial = partial(my_setup, 1) my_teardown_partial = partial(my_teardown, 2) def test_hello(): print(values) assert values == [1] def test_world(): print(values) assert values == [1,2] test_hello.setup = my_setup_partial test_hello.teardown = my_teardown_partial """ ) result = pytester.runpytest( p, "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" ) result.stdout.fnmatch_lines(["*2 passed*"]) def test_module_level_setup(pytester: Pytester) -> None: pytester.makepyfile( """ from nose.tools import with_setup items = {} def setup(): items.setdefault("setup", []).append("up") def teardown(): items.setdefault("setup", []).append("down") def setup2(): items.setdefault("setup2", []).append("up") def teardown2(): items.setdefault("setup2", []).append("down") def test_setup_module_setup(): assert items["setup"] == ["up"] def test_setup_module_setup_again(): assert items["setup"] == ["up"] @with_setup(setup2, teardown2) def test_local_setup(): assert items["setup"] == ["up"] assert items["setup2"] == ["up"] @with_setup(setup2, teardown2) def test_local_setup_again(): assert items["setup"] == ["up"] assert items["setup2"] == ["up", "down", "up"] """ ) result = pytester.runpytest( "-p", "nose", "-Wignore::pytest.PytestRemovedIn8Warning" ) result.stdout.fnmatch_lines(["*4 passed*"]) def test_nose_style_setup_teardown(pytester: Pytester) -> None: pytester.makepyfile( """ values = [] def setup_module(): values.append(1) def teardown_module(): del values[0] def test_hello(): assert values == [1] def test_world(): assert values == [1] """ ) result = pytester.runpytest("-p", "nose") result.stdout.fnmatch_lines(["*2 passed*"]) def test_fixtures_nose_setup_issue8394(pytester: Pytester) -> None: pytester.makepyfile( """ def setup_module(): pass def teardown_module(): pass def setup_function(func): pass def teardown_function(func): pass def test_world(): pass class Test(object): def setup_class(cls): pass def teardown_class(cls): pass def setup_method(self, meth): pass def teardown_method(self, meth): pass def test_method(self): pass """ ) match = "*no docstring available*" result = pytester.runpytest("--fixtures") assert result.ret == 0 result.stdout.no_fnmatch_line(match) result = pytester.runpytest("--fixtures", "-v") assert result.ret == 0 result.stdout.fnmatch_lines([match, match, match, match]) def test_nose_setup_ordering(pytester: Pytester) -> None: pytester.makepyfile( """ def setup_module(mod): mod.visited = True class TestClass(object): def setup(self): assert visited self.visited_cls = True def test_first(self): assert visited assert self.visited_cls """ ) result = pytester.runpytest("-Wignore::pytest.PytestRemovedIn8Warning") result.stdout.fnmatch_lines(["*1 passed*"]) def test_apiwrapper_problem_issue260(pytester: Pytester) -> None: # this would end up trying a call an optional teardown on the class # for plain unittests we don't want nose behaviour pytester.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 = pytester.runpytest() result.assert_outcomes(passed=1) def test_setup_teardown_linking_issue265(pytester: Pytester) -> None: # we accidentally didn't integrate nose setupstate with normal setupstate # this test ensures that won't happen again pytester.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") ''' ) reprec = pytester.runpytest() reprec.assert_outcomes(passed=1, skipped=1) def test_SkipTest_during_collection(pytester: Pytester) -> None: p = pytester.makepyfile( """ import nose raise nose.SkipTest("during collection") def test_failing(): assert False """ ) result = pytester.runpytest(p) result.assert_outcomes(skipped=1, warnings=0) def test_SkipTest_in_test(pytester: Pytester) -> None: pytester.makepyfile( """ import nose def test_skipping(): raise nose.SkipTest("in test") """ ) reprec = pytester.inline_run() reprec.assertoutcome(skipped=1) def test_istest_function_decorator(pytester: Pytester) -> None: p = pytester.makepyfile( """ import nose.tools @nose.tools.istest def not_test_prefix(): pass """ ) result = pytester.runpytest(p) result.assert_outcomes(passed=1) def test_nottest_function_decorator(pytester: Pytester) -> None: pytester.makepyfile( """ import nose.tools @nose.tools.nottest def test_prefix(): pass """ ) reprec = pytester.inline_run() assert not reprec.getfailedcollections() calls = reprec.getreports("pytest_runtest_logreport") assert not calls def test_istest_class_decorator(pytester: Pytester) -> None: p = pytester.makepyfile( """ import nose.tools @nose.tools.istest class NotTestPrefix(object): def test_method(self): pass """ ) result = pytester.runpytest(p) result.assert_outcomes(passed=1) def test_nottest_class_decorator(pytester: Pytester) -> None: pytester.makepyfile( """ import nose.tools @nose.tools.nottest class TestPrefix(object): def test_method(self): pass """ ) reprec = pytester.inline_run() assert not reprec.getfailedcollections() calls = reprec.getreports("pytest_runtest_logreport") assert not calls def test_skip_test_with_unicode(pytester: Pytester) -> None: pytester.makepyfile( """\ import unittest class TestClass(): def test_io(self): raise unittest.SkipTest('😊') """ ) result = pytester.runpytest() result.stdout.fnmatch_lines(["* 1 skipped *"]) def test_raises(pytester: Pytester) -> None: pytester.makepyfile( """ from nose.tools import raises @raises(RuntimeError) def test_raises_runtimeerror(): raise RuntimeError @raises(Exception) def test_raises_baseexception_not_caught(): raise BaseException @raises(BaseException) def test_raises_baseexception_caught(): raise BaseException """ ) result = pytester.runpytest("-vv") result.stdout.fnmatch_lines( [ "test_raises.py::test_raises_runtimeerror PASSED*", "test_raises.py::test_raises_baseexception_not_caught FAILED*", "test_raises.py::test_raises_baseexception_caught PASSED*", "*= FAILURES =*", "*_ test_raises_baseexception_not_caught _*", "", "arg = (), kw = {}", "", " def newfunc(*arg, **kw):", " try:", "> func(*arg, **kw)", "", "*/nose/*: ", "_ _ *", "", " @raises(Exception)", " def test_raises_baseexception_not_caught():", "> raise BaseException", "E BaseException", "", "test_raises.py:9: BaseException", "* 1 failed, 2 passed *", ] ) def test_nose_setup_skipped_if_non_callable(pytester: Pytester) -> None: """Regression test for #9391.""" p = pytester.makepyfile( __init__="", setup=""" """, teardown=""" """, test_it=""" from . import setup, teardown def test_it(): pass """, ) result = pytester.runpytest(p.parent, "-p", "nose") assert result.ret == 0 @pytest.mark.parametrize("fixture_name", ("teardown", "teardown_class")) def test_teardown_fixture_not_called_directly(fixture_name, pytester: Pytester) -> None: """Regression test for #10597.""" p = pytester.makepyfile( f""" import pytest class TestHello: @pytest.fixture def {fixture_name}(self): yield def test_hello(self, {fixture_name}): assert True """ ) result = pytester.runpytest(p, "-p", "nose") assert result.ret == 0