520 lines
13 KiB
Python
520 lines
13 KiB
Python
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")
|
|
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")
|
|
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")
|
|
result.stdout.fnmatch_lines(["*TypeError: <lambda>()*"])
|
|
|
|
|
|
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")
|
|
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")
|
|
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()
|
|
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, "-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
|