2010-11-18 21:56:16 +08:00
|
|
|
""" run test suites written for nose. """
|
2017-03-17 09:21:30 +08:00
|
|
|
from __future__ import absolute_import, division, print_function
|
2009-08-10 17:27:13 +08:00
|
|
|
|
|
|
|
import sys
|
2014-03-14 21:04:54 +08:00
|
|
|
|
|
|
|
import py
|
2017-03-17 03:51:22 +08:00
|
|
|
from _pytest import unittest, runner, python
|
|
|
|
from _pytest.config import hookimpl
|
2013-02-08 00:53:13 +08:00
|
|
|
|
2014-03-14 21:04:54 +08:00
|
|
|
|
|
|
|
def get_skip_exceptions():
|
|
|
|
skip_classes = set()
|
|
|
|
for module_name in ('unittest', 'unittest2', 'nose'):
|
|
|
|
mod = sys.modules.get(module_name)
|
|
|
|
if hasattr(mod, 'SkipTest'):
|
|
|
|
skip_classes.add(mod.SkipTest)
|
|
|
|
return tuple(skip_classes)
|
|
|
|
|
|
|
|
|
2014-10-09 02:23:40 +08:00
|
|
|
def pytest_runtest_makereport(item, call):
|
2014-03-14 22:29:42 +08:00
|
|
|
if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()):
|
|
|
|
# let's substitute the excinfo with a pytest.skip one
|
2017-03-17 03:51:22 +08:00
|
|
|
call2 = call.__class__(
|
|
|
|
lambda: runner.skip(str(call.excinfo.value)), call.when)
|
2014-03-14 22:29:42 +08:00
|
|
|
call.excinfo = call2.excinfo
|
2009-08-10 17:27:13 +08:00
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2017-03-17 03:51:22 +08:00
|
|
|
@hookimpl(trylast=True)
|
2009-08-10 17:27:13 +08:00
|
|
|
def pytest_runtest_setup(item):
|
2013-02-08 00:53:13 +08:00
|
|
|
if is_potential_nosetest(item):
|
2017-03-17 03:51:22 +08:00
|
|
|
if isinstance(item.parent, python.Generator):
|
2010-07-27 03:15:15 +08:00
|
|
|
gen = item.parent
|
2009-08-10 17:27:13 +08:00
|
|
|
if not hasattr(gen, '_nosegensetup'):
|
|
|
|
call_optional(gen.obj, 'setup')
|
2017-03-17 03:51:22 +08:00
|
|
|
if isinstance(gen.parent, python.Instance):
|
2009-08-10 17:27:13 +08:00
|
|
|
call_optional(gen.parent.obj, 'setup')
|
|
|
|
gen._nosegensetup = True
|
2009-10-23 21:11:53 +08:00
|
|
|
if not call_optional(item.obj, 'setup'):
|
|
|
|
# call module level setup if there is no object level one
|
|
|
|
call_optional(item.parent.obj, 'setup')
|
2017-07-17 07:25:09 +08:00
|
|
|
# XXX this implies we only call teardown when setup worked
|
2013-03-25 17:52:02 +08:00
|
|
|
item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)
|
2009-08-10 17:27:13 +08:00
|
|
|
|
2013-03-25 17:52:02 +08:00
|
|
|
def teardown_nose(item):
|
2013-02-08 00:53:13 +08:00
|
|
|
if is_potential_nosetest(item):
|
2009-10-23 21:27:59 +08:00
|
|
|
if not call_optional(item.obj, 'teardown'):
|
|
|
|
call_optional(item.parent.obj, 'teardown')
|
2017-07-17 07:25:09 +08:00
|
|
|
# if hasattr(item.parent, '_nosegensetup'):
|
2009-08-10 17:27:13 +08:00
|
|
|
# #call_optional(item._nosegensetup, 'teardown')
|
|
|
|
# del item.parent._nosegensetup
|
|
|
|
|
2014-03-14 21:04:54 +08:00
|
|
|
|
2009-08-10 17:27:13 +08:00
|
|
|
def pytest_make_collect_report(collector):
|
2017-03-17 03:51:22 +08:00
|
|
|
if isinstance(collector, python.Generator):
|
2009-08-10 17:27:13 +08:00
|
|
|
call_optional(collector.obj, 'setup')
|
|
|
|
|
2013-02-08 00:53:13 +08:00
|
|
|
|
|
|
|
def is_potential_nosetest(item):
|
|
|
|
# extra check needed since we do not do nose style setup/teardown
|
|
|
|
# on direct unittest style classes
|
2017-03-17 03:51:22 +08:00
|
|
|
return isinstance(item, python.Function) and \
|
2013-02-08 00:53:13 +08:00
|
|
|
not isinstance(item, unittest.TestCaseFunction)
|
|
|
|
|
|
|
|
|
2009-08-10 17:27:13 +08:00
|
|
|
def call_optional(obj, name):
|
|
|
|
method = getattr(obj, name, None)
|
2013-02-07 17:41:07 +08:00
|
|
|
isfixture = hasattr(method, "_pytestfixturefunction")
|
|
|
|
if method is not None and not isfixture and py.builtin.callable(method):
|
2010-09-03 18:27:47 +08:00
|
|
|
# If there's any problems allow the exception to raise rather than
|
|
|
|
# silently ignoring them
|
|
|
|
method()
|
|
|
|
return True
|