[py-svn] pytest commit 809c2914a73d: introduce an option that avoids discovery of classes other than unittest.TestCase in modules
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Sat Nov 6 23:44:50 CET 2010
# HG changeset patch -- Bitbucket.org
# Project pytest
# URL http://bitbucket.org/hpk42/pytest/overview
# User holger krekel <holger at merlinux.eu>
# Date 1289083548 -3600
# Node ID 809c2914a73dd1604f9188842f13f9cb8f42a2ff
# Parent c75f441489d31835abeeabd20c0f6cfd7441b269
introduce an option that avoids discovery of classes other than unittest.TestCase in modules
importing unittest.
--- a/testing/acceptance_test.py
+++ b/testing/acceptance_test.py
@@ -294,6 +294,7 @@ class TestInvocationVariants:
assert not retcode
out, err = capsys.readouterr()
assert "--help" in out
+ pytest.raises(ValueError, lambda: pytest.main(retcode))
def test_invoke_with_path(self, testdir, capsys):
retcode = testdir.pytestmain(testdir.tmpdir)
@@ -330,3 +331,18 @@ class TestInvocationVariants:
result.stderr.fnmatch_lines([
"ERROR*file*or*package*not*found*",
])
+
+
+ def test_noclass_discovery_if_not_testcase(self, testdir):
+ testpath = testdir.makepyfile("""
+ import unittest
+ import py
+ class TestHello(object):
+ def test_hello(self):
+ assert self.attr
+
+ class RealTest(TestHello, unittest.TestCase):
+ attr = 42
+ """)
+ reprec = testdir.inline_run(testpath)
+ reprec.assertoutcome(passed=1)
--- a/pytest/plugin/python.py
+++ b/pytest/plugin/python.py
@@ -59,6 +59,8 @@ def pytest_pycollect_makeitem(__multical
if res is not None:
return res
if collector._istestclasscandidate(name, obj):
+ if hasattr(collector.obj, 'unittest'):
+ return # we assume it's a mixin class for a TestCase derived one
return Class(name, parent=collector)
elif collector.funcnamefilter(name) and hasattr(obj, '__call__'):
if is_generator(obj):
@@ -124,6 +126,7 @@ class PyobjMixin(object):
return self._fslineno
def reportinfo(self):
+ # XXX caching?
obj = self.obj
if hasattr(obj, 'compat_co_firstlineno'):
# nose compatibility
--- a/testing/plugin/test_assertion.py
+++ b/testing/plugin/test_assertion.py
@@ -161,6 +161,15 @@ def test_functional(testdir):
result = testdir.runpytest("--no-assert")
assert "3 == 4" not in result.stdout.str()
+def test_AssertionErrorIdentity(testdir):
+ testdir.makepyfile("""
+ def test_hello():
+ import exceptions
+ assert AssertionError is exceptions.AssertionError
+ """)
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines(["*1 passed*"])
+
def test_triple_quoted_string_issue113(testdir):
testdir.makepyfile("""
def test_hello():
--- a/tox.ini
+++ b/tox.ini
@@ -52,5 +52,6 @@ commands=
[pytest]
minversion=2.0
plugins=pytester
-addargs=-rfx
+addopts=-rfx --pyargs
rsyncdirs=pytest testing
+
--- a/pytest/plugin/unittest.py
+++ b/pytest/plugin/unittest.py
@@ -1,12 +1,13 @@
-""" support discovery and running of traditional "unittest.py" style tests. """
+""" discovery and running of std-library "unittest" style tests. """
import py
import sys
def pytest_pycollect_makeitem(collector, name, obj):
- if 'unittest' not in sys.modules:
- return # nobody derived unittest.TestCase
+ unittest = sys.modules.get('unittest')
+ if unittest is None:
+ return # nobody can have derived unittest.TestCase
try:
- isunit = issubclass(obj, py.std.unittest.TestCase)
+ isunit = issubclass(obj, unittest.TestCase)
except KeyboardInterrupt:
raise
except Exception:
--- a/pytest/plugin/assertion.py
+++ b/pytest/plugin/assertion.py
@@ -3,6 +3,7 @@ support for presented detailed informati
"""
import py
import sys
+from pytest.plugin.monkeypatch import monkeypatch
def pytest_addoption(parser):
group = parser.getgroup("debugconfig")
@@ -15,25 +16,21 @@ def pytest_configure(config):
# py._code._assertionnew to detect this plugin was loaded and in
# turn call the hooks defined here as part of the
# DebugInterpreter.
+ config._monkeypatch = m = monkeypatch()
if not config.getvalue("noassert") and not config.getvalue("nomagic"):
warn_about_missing_assertion()
- config._oldassertion = py.builtin.builtins.AssertionError
- config._oldbinrepr = py.code._reprcompare
- py.builtin.builtins.AssertionError = py.code._AssertionError
def callbinrepr(op, left, right):
hook_result = config.hook.pytest_assertrepr_compare(
config=config, op=op, left=left, right=right)
for new_expl in hook_result:
if new_expl:
return '\n~'.join(new_expl)
- py.code._reprcompare = callbinrepr
+ m.setattr(py.builtin.builtins,
+ 'AssertionError', py.code._AssertionError)
+ m.setattr(py.code, '_reprcompare', callbinrepr)
def pytest_unconfigure(config):
- if hasattr(config, '_oldassertion'):
- py.builtin.builtins.AssertionError = config._oldassertion
- py.code._reprcompare = config._oldbinrepr
- del config._oldassertion
- del config._oldbinrepr
+ config._monkeypatch.undo()
def warn_about_missing_assertion():
try:
--- a/pytest/main.py
+++ b/pytest/main.py
@@ -403,7 +403,11 @@ def main(args=None, plugins=None):
if args is None:
args = sys.argv[1:]
elif not isinstance(args, (tuple, list)):
- args = py.std.shlex.split(str(args))
+ if isinstance(args, py.path.local):
+ args = str(args)
+ if not isinstance(args, str):
+ raise ValueError("not a string or argument list: %r" % (args,))
+ args = py.std.shlex.split(args)
if _preinit:
_pluginmanager = _preinit.pop(0)
else: # subsequent calls to main will create a fresh instance
More information about the pytest-commit
mailing list