
* Porting: substitute nose with ytest This huge commit substitutes nose with pytest as a testing system. Things done here: * deleted external/nose as it is no longer used * moved mock resources in their own directory 'test/mock/' * ported two tests (cmd/find, build_system) to pytest native syntax as an example * build_environment, log: used monkeypatch instead of try/catch * moved global mocking of fetch_cache to an auto-used fixture * moved global mocking from test/__init__.py to conftest.py * made `spack test` a wrapper around pytest * run-unit-tests: avoid running python 2.6 tests under coverage to speed them up * use `pytest --cov` instead of coverage run to cut down testing time * mock/packages_test: moved mock yaml configuration to files instead of leaving it in the code as string literals * concretize.py: ported tests to native pytest, reverted multiprocessing in pytest.ini as it was creating the wrong report for coveralls * conftest.py, fixtures: added docstrings * concretize_preferences.py: uses fixtures instead of subclassing MockPackagesTest * directory_layout.py: uses fixtures instead of subclassing MockPackagesTest * install.py: uses fixtures instead of subclassing MockPackagesTest * optional_deps.py: uses fixtures instead of subclassing MockPackagesTest optional_deps.py: uses fixtures instead of subclassing MockPackagesTest * packages.py: uses fixtures instead of subclassing MockPackagesTest * provider_index.py: uses fixtures instead of subclassing MockPackagesTest * spec_yaml.py: uses fixtures instead of subclassing MockPackagesTest * multimethod.py: uses fixtures instead of subclassing MockPackagesTest * install.py: now uses mock_archive_url * git_fetch.py: uses fixtures instead of subclassing MockPackagesTest * hg_fetch.py: uses fixtures instead of subclassing MockPackagesTest * svn_fetch.py, mirror.py: uses fixtures instead of subclassing MockPackagesTest repo.py: deleted * test_compiler_cmd.py: uses fixtures instead of subclassing MockPackagesTest * cmd/module.py, cmd/uninstall.py: uses fixtures instead of subclassing MockDatabase * database.py: uses fixtures instead of subclassing MockDatabase, removed mock/database * pytest: uncluttering fixture implementations * database: changing the scope to 'module' * config.py: uses fixtures instead of subclassing MockPackagesTest * spec_dag.py, spec_semantics.py: uses fixtures instead of subclassing MockPackagesTest * stage.py: uses fixtures instead of subclassing MockPackagesTest. Removed mock directory * pytest: added docstrings to all the fixtures * pytest: final cleanup * build_system_guess.py: fixed naming and docstrings as suggested by @scheibelp * spec_syntax.py: added expected failure on parsing multiple specs closes #1976 * Add pytest and pytest-cov to Spack externals. * Make `spack flake8` ignore externals. * run-unit-tests runs spack test and not pytest. * Remove all the special stuff for `spack test` - Remove `conftest.py` magic and all the special case stuff in `bin/spack` - Spack commands can optionally take unknown arguments, if they want to handle them. - `spack test` is now a command like the others. - `spack test` now just delegates its arguments to `pytest`, but it does it by receiving unknown arguments and NOT taking an explicit help argument. * Fix error in fixtures. * Improve `spack test` command a bit. - Now supports an approximation of the old simple interface - Also supports full pytest options if you want them. * Use external coverage instead of pytest-cov * Make coverage use parallel-mode. * change __init__.py docs to include pytest
72 lines
2.5 KiB
Python
72 lines
2.5 KiB
Python
""" run test suites written for nose. """
|
|
|
|
import sys
|
|
|
|
import py
|
|
import pytest
|
|
from _pytest import unittest
|
|
|
|
|
|
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)
|
|
|
|
|
|
def pytest_runtest_makereport(item, call):
|
|
if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()):
|
|
# let's substitute the excinfo with a pytest.skip one
|
|
call2 = call.__class__(lambda:
|
|
pytest.skip(str(call.excinfo.value)), call.when)
|
|
call.excinfo = call2.excinfo
|
|
|
|
|
|
@pytest.hookimpl(trylast=True)
|
|
def pytest_runtest_setup(item):
|
|
if is_potential_nosetest(item):
|
|
if isinstance(item.parent, pytest.Generator):
|
|
gen = item.parent
|
|
if not hasattr(gen, '_nosegensetup'):
|
|
call_optional(gen.obj, 'setup')
|
|
if isinstance(gen.parent, pytest.Instance):
|
|
call_optional(gen.parent.obj, 'setup')
|
|
gen._nosegensetup = True
|
|
if not call_optional(item.obj, 'setup'):
|
|
# call module level setup if there is no object level one
|
|
call_optional(item.parent.obj, 'setup')
|
|
#XXX this implies we only call teardown when setup worked
|
|
item.session._setupstate.addfinalizer((lambda: teardown_nose(item)), item)
|
|
|
|
def teardown_nose(item):
|
|
if is_potential_nosetest(item):
|
|
if not call_optional(item.obj, 'teardown'):
|
|
call_optional(item.parent.obj, 'teardown')
|
|
#if hasattr(item.parent, '_nosegensetup'):
|
|
# #call_optional(item._nosegensetup, 'teardown')
|
|
# del item.parent._nosegensetup
|
|
|
|
|
|
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")
|
|
if method is not None and not isfixture and py.builtin.callable(method):
|
|
# If there's any problems allow the exception to raise rather than
|
|
# silently ignoring them
|
|
method()
|
|
return True
|