Fixed race condition with SkipTest when module not in sys.modules on collection.

This commit is contained in:
schlamar 2014-03-14 14:04:54 +01:00
parent f5b992f68a
commit 94b1ce65c6
4 changed files with 38 additions and 16 deletions

View File

@ -408,10 +408,6 @@ class Collector(Node):
and thus iteratively build a tree.
"""
# the set of exceptions to interpret as "Skip the whole module" during
# collection
skip_exceptions = (Skipped,)
class CollectError(Exception):
""" an error during collection, contains a custom message. """

View File

@ -1,17 +1,32 @@
""" run test suites written for nose. """
import pytest, py
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(__multicall__, item, call):
SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None)
if SkipTest:
if call.excinfo and call.excinfo.errisinstance(SkipTest):
if not call.excinfo:
return
for skip_exc in get_skip_exceptions():
if call.excinfo.errisinstance(skip_exc):
# 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
return
@pytest.mark.trylast
@ -38,13 +53,8 @@ def teardown_nose(item):
# #call_optional(item._nosegensetup, 'teardown')
# del item.parent._nosegensetup
def pytest_make_collect_report(collector):
SkipTest = getattr(sys.modules.get('unittest', None), 'SkipTest', None)
if SkipTest is not None:
collector.skip_exceptions += (SkipTest,)
SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None)
if SkipTest is not None:
collector.skip_exceptions += (SkipTest,)
if isinstance(collector, pytest.Generator):
call_optional(collector.obj, 'setup')

View File

@ -267,7 +267,9 @@ def pytest_make_collect_report(collector):
if not call.excinfo:
outcome = "passed"
else:
if call.excinfo.errisinstance(collector.skip_exceptions):
from _pytest import nose
skip_exceptions = (Skipped,) + nose.get_skip_exceptions()
if call.excinfo.errisinstance(skip_exceptions):
outcome = "skipped"
r = collector._repr_failure_py(call.excinfo, "line").reprcrash
longrepr = (str(r.path), r.lineno, r.message)

View File

@ -330,12 +330,26 @@ def test_setup_teardown_linking_issue265(testdir):
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1, skipped=1)
def test_SkipTest_during_collection(testdir):
testdir.makepyfile("""
p = testdir.makepyfile("""
import nose
raise nose.SkipTest("during collection")
def test_failing():
assert False
""")
result = testdir.runpytest(p)
outcome = result.parseoutcomes()
outcome.pop('seconds')
assert outcome == dict(skipped=1)
def test_SkipTest_in_test(testdir):
testdir.makepyfile("""
import nose
def test_skipping():
raise nose.SkipTest("in test")
""")
reprec = testdir.inline_run()
reprec.assertoutcome(skipped=1)