Merge pull request #4443 from asottile/deprecate_raises_exec

Deprecate `raises(..., 'code(as_a_string)')` / `warns(..., 'code(as_a_string)')`.
This commit is contained in:
Anthony Sottile 2018-11-29 11:57:56 -08:00 committed by GitHub
commit 1d86247b2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 140 additions and 96 deletions

View File

@ -0,0 +1 @@
Deprecate ``raises(..., 'code(as_a_string)')`` and ``warns(..., 'code(as_a_string)')``. See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec

View File

@ -100,10 +100,9 @@ If you want to write test code that works on Python 2.4 as well,
you may also use two other ways to test for an expected exception:: you may also use two other ways to test for an expected exception::
pytest.raises(ExpectedException, func, *args, **kwargs) pytest.raises(ExpectedException, func, *args, **kwargs)
pytest.raises(ExpectedException, "func(*args, **kwargs)")
both of which execute the specified function with args and kwargs and which will execute the specified function with args and kwargs and
asserts that the given ``ExpectedException`` is raised. The reporter will assert that the given ``ExpectedException`` is raised. The reporter will
provide you with helpful output in case of failures such as *no provide you with helpful output in case of failures such as *no
exception* or *wrong exception*. exception* or *wrong exception*.

View File

@ -14,6 +14,41 @@ Below is a complete list of all pytest features which are considered deprecated.
:class:`_pytest.warning_types.PytestWarning` or subclasses, which can be filtered using :class:`_pytest.warning_types.PytestWarning` or subclasses, which can be filtered using
:ref:`standard warning filters <warnings>`. :ref:`standard warning filters <warnings>`.
.. _raises-warns-exec:
``raises`` / ``warns`` with a string as the second argument
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 4.1
Use the context manager form of these instead. When necessary, invoke ``exec``
directly.
Example:
.. code-block:: python
pytest.raises(ZeroDivisionError, "1 / 0")
pytest.raises(SyntaxError, "a $ b")
pytest.warns(DeprecationWarning, "my_function()")
pytest.warns(SyntaxWarning, "assert(1, 2)")
Becomes:
.. code-block:: python
with pytest.raises(ZeroDivisionError):
1 / 0
with pytest.raises(SyntaxError):
exec("a $ b") # exec is required for invalid syntax
with pytest.warns(DeprecationWarning):
my_function()
with pytest.warns(SyntaxWarning):
exec("assert(1, 2)") # exec is used to avoid a top-level warning
Internal classes accessed through ``Node`` Internal classes accessed through ``Node``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -165,11 +165,11 @@ def globf(x):
class TestRaises(object): class TestRaises(object):
def test_raises(self): def test_raises(self):
s = "qwe" # NOQA s = "qwe"
raises(TypeError, "int(s)") raises(TypeError, int, s)
def test_raises_doesnt(self): def test_raises_doesnt(self):
raises(IOError, "int('3')") raises(IOError, int, "3")
def test_raise(self): def test_raise(self):
raise ValueError("demo error") raise ValueError("demo error")

View File

@ -388,7 +388,8 @@ parametrizer`_ but in a lot less code::
assert a == b assert a == b
def test_zerodivision(self, a, b): def test_zerodivision(self, a, b):
pytest.raises(ZeroDivisionError, "a/b") with pytest.raises(ZeroDivisionError):
a / b
Our test generator looks up a class-level definition which specifies which Our test generator looks up a class-level definition which specifies which
argument sets to use for each test function. Let's run it: argument sets to use for each test function. Let's run it:

View File

@ -92,6 +92,15 @@ NODE_WARN = RemovedInPytest4Warning(
"Node.warn(code, message) form has been deprecated, use Node.warn(warning_instance) instead." "Node.warn(code, message) form has been deprecated, use Node.warn(warning_instance) instead."
) )
RAISES_EXEC = PytestDeprecationWarning(
"raises(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly\n\n"
"See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
)
WARNS_EXEC = PytestDeprecationWarning(
"warns(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly.\n\n"
"See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
)
RECORD_XML_PROPERTY = RemovedInPytest4Warning( RECORD_XML_PROPERTY = RemovedInPytest4Warning(
'Fixture renamed from "record_xml_property" to "record_property" as user ' 'Fixture renamed from "record_xml_property" to "record_property" as user '
"properties are now available to all reporters.\n" "properties are now available to all reporters.\n"

View File

@ -1,6 +1,9 @@
from __future__ import absolute_import
import math import math
import pprint import pprint
import sys import sys
import warnings
from decimal import Decimal from decimal import Decimal
from numbers import Number from numbers import Number
@ -14,6 +17,7 @@ from _pytest.compat import isclass
from _pytest.compat import Mapping from _pytest.compat import Mapping
from _pytest.compat import Sequence from _pytest.compat import Sequence
from _pytest.compat import STRING_TYPES from _pytest.compat import STRING_TYPES
from _pytest.deprecated import RAISES_EXEC
from _pytest.outcomes import fail from _pytest.outcomes import fail
BASE_TYPE = (type, STRING_TYPES) BASE_TYPE = (type, STRING_TYPES)
@ -604,9 +608,9 @@ def raises(expected_exception, *args, **kwargs):
>>> with raises(ValueError, match=r'must be \d+$'): >>> with raises(ValueError, match=r'must be \d+$'):
... raise ValueError("value must be 42") ... raise ValueError("value must be 42")
**Legacy forms** **Legacy form**
The forms below are fully supported but are discouraged for new code because the The form below is fully supported but discouraged for new code because the
context manager form is regarded as more readable and less error-prone. context manager form is regarded as more readable and less error-prone.
It is possible to specify a callable by passing a to-be-called lambda:: It is possible to specify a callable by passing a to-be-called lambda::
@ -623,14 +627,6 @@ def raises(expected_exception, *args, **kwargs):
>>> raises(ZeroDivisionError, f, x=0) >>> raises(ZeroDivisionError, f, x=0)
<ExceptionInfo ...> <ExceptionInfo ...>
It is also possible to pass a string to be evaluated at runtime::
>>> raises(ZeroDivisionError, "f(0)")
<ExceptionInfo ...>
The string will be evaluated using the same ``locals()`` and ``globals()``
at the moment of the ``raises`` call.
.. currentmodule:: _pytest._code .. currentmodule:: _pytest._code
Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`. Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`.
@ -672,6 +668,7 @@ def raises(expected_exception, *args, **kwargs):
raise TypeError(msg) raise TypeError(msg)
return RaisesContext(expected_exception, message, match_expr) return RaisesContext(expected_exception, message, match_expr)
elif isinstance(args[0], str): elif isinstance(args[0], str):
warnings.warn(RAISES_EXEC, stacklevel=2)
code, = args code, = args
assert isinstance(code, str) assert isinstance(code, str)
frame = sys._getframe(1) frame = sys._getframe(1)

View File

@ -11,6 +11,7 @@ import warnings
import six import six
import _pytest._code import _pytest._code
from _pytest.deprecated import WARNS_EXEC
from _pytest.fixtures import yield_fixture from _pytest.fixtures import yield_fixture
from _pytest.outcomes import fail from _pytest.outcomes import fail
@ -89,6 +90,7 @@ def warns(expected_warning, *args, **kwargs):
match_expr = kwargs.pop("match") match_expr = kwargs.pop("match")
return WarningsChecker(expected_warning, match_expr=match_expr) return WarningsChecker(expected_warning, match_expr=match_expr)
elif isinstance(args[0], str): elif isinstance(args[0], str):
warnings.warn(WARNS_EXEC, stacklevel=2)
code, = args code, = args
assert isinstance(code, str) assert isinstance(code, str)
frame = sys._getframe(1) frame = sys._getframe(1)

View File

@ -37,7 +37,7 @@ def test_code_with_class():
class A(object): class A(object):
pass pass
pytest.raises(TypeError, "_pytest._code.Code(A)") pytest.raises(TypeError, _pytest._code.Code, A)
def x(): def x():

View File

@ -180,7 +180,8 @@ class TestTraceback_f_g_h(object):
def test_traceback_cut_excludepath(self, testdir): def test_traceback_cut_excludepath(self, testdir):
p = testdir.makepyfile("def f(): raise ValueError") p = testdir.makepyfile("def f(): raise ValueError")
excinfo = pytest.raises(ValueError, "p.pyimport().f()") with pytest.raises(ValueError) as excinfo:
p.pyimport().f()
basedir = py.path.local(pytest.__file__).dirpath() basedir = py.path.local(pytest.__file__).dirpath()
newtraceback = excinfo.traceback.cut(excludepath=basedir) newtraceback = excinfo.traceback.cut(excludepath=basedir)
for x in newtraceback: for x in newtraceback:
@ -336,7 +337,8 @@ class TestTraceback_f_g_h(object):
def test_excinfo_exconly(): def test_excinfo_exconly():
excinfo = pytest.raises(ValueError, h) excinfo = pytest.raises(ValueError, h)
assert excinfo.exconly().startswith("ValueError") assert excinfo.exconly().startswith("ValueError")
excinfo = pytest.raises(ValueError, "raise ValueError('hello\\nworld')") with pytest.raises(ValueError) as excinfo:
raise ValueError("hello\nworld")
msg = excinfo.exconly(tryshort=True) msg = excinfo.exconly(tryshort=True)
assert msg.startswith("ValueError") assert msg.startswith("ValueError")
assert msg.endswith("world") assert msg.endswith("world")

View File

@ -6,6 +6,7 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import ast
import inspect import inspect
import sys import sys
@ -14,7 +15,6 @@ import six
import _pytest._code import _pytest._code
import pytest import pytest
from _pytest._code import Source from _pytest._code import Source
from _pytest._code.source import ast
astonly = pytest.mark.nothing astonly = pytest.mark.nothing
@ -306,8 +306,6 @@ class TestSourceParsingAndCompiling(object):
pytest.raises(SyntaxError, lambda: source.getstatementrange(0)) pytest.raises(SyntaxError, lambda: source.getstatementrange(0))
def test_compile_to_ast(self): def test_compile_to_ast(self):
import ast
source = Source("x = 4") source = Source("x = 4")
mod = source.compile(flag=ast.PyCF_ONLY_AST) mod = source.compile(flag=ast.PyCF_ONLY_AST)
assert isinstance(mod, ast.Module) assert isinstance(mod, ast.Module)
@ -317,10 +315,9 @@ class TestSourceParsingAndCompiling(object):
co = self.source.compile() co = self.source.compile()
six.exec_(co, globals()) six.exec_(co, globals())
f(7) f(7)
excinfo = pytest.raises(AssertionError, "f(6)") excinfo = pytest.raises(AssertionError, f, 6)
frame = excinfo.traceback[-1].frame frame = excinfo.traceback[-1].frame
stmt = frame.code.fullsource.getstatement(frame.lineno) stmt = frame.code.fullsource.getstatement(frame.lineno)
# print "block", str(block)
assert str(stmt).strip().startswith("assert") assert str(stmt).strip().startswith("assert")
@pytest.mark.parametrize("name", ["", None, "my"]) @pytest.mark.parametrize("name", ["", None, "my"])
@ -361,17 +358,13 @@ def test_getline_finally():
def c(): def c():
pass pass
excinfo = pytest.raises( with pytest.raises(TypeError) as excinfo:
TypeError, teardown = None
""" try:
teardown = None c(1)
try: finally:
c(1) if teardown:
finally: teardown()
if teardown:
teardown()
""",
)
source = excinfo.traceback[-1].statement source = excinfo.traceback[-1].statement
assert str(source).strip() == "c(1)" assert str(source).strip() == "c(1)"

View File

@ -3,4 +3,4 @@ import pytest
@pytest.fixture @pytest.fixture
def arg2(request): def arg2(request):
pytest.raises(Exception, "request.getfixturevalue('arg1')") pytest.raises(Exception, request.getfixturevalue, "arg1")

View File

@ -325,7 +325,7 @@ class TestGenerator(object):
assert len(colitems) == 1 assert len(colitems) == 1
gencol = colitems[0] gencol = colitems[0]
assert isinstance(gencol, pytest.Generator) assert isinstance(gencol, pytest.Generator)
pytest.raises(ValueError, "gencol.collect()") pytest.raises(ValueError, gencol.collect)
def test_generative_methods_with_explicit_names(self, testdir): def test_generative_methods_with_explicit_names(self, testdir):
modcol = testdir.getmodulecol( modcol = testdir.getmodulecol(
@ -1103,7 +1103,8 @@ def test_modulecol_roundtrip(testdir):
class TestTracebackCutting(object): class TestTracebackCutting(object):
def test_skip_simple(self): def test_skip_simple(self):
excinfo = pytest.raises(pytest.skip.Exception, 'pytest.skip("xxx")') with pytest.raises(pytest.skip.Exception) as excinfo:
pytest.skip("xxx")
assert excinfo.traceback[-1].frame.code.name == "skip" assert excinfo.traceback[-1].frame.code.name == "skip"
assert excinfo.traceback[-1].ishidden() assert excinfo.traceback[-1].ishidden()

View File

@ -906,7 +906,8 @@ class TestRequestMarking(object):
assert "skipif" not in item1.keywords assert "skipif" not in item1.keywords
req1.applymarker(pytest.mark.skipif) req1.applymarker(pytest.mark.skipif)
assert "skipif" in item1.keywords assert "skipif" in item1.keywords
pytest.raises(ValueError, "req1.applymarker(42)") with pytest.raises(ValueError):
req1.applymarker(42)
def test_accesskeywords(self, testdir): def test_accesskeywords(self, testdir):
testdir.makepyfile( testdir.makepyfile(

View File

@ -70,11 +70,11 @@ class TestMetafunc(object):
pass pass
metafunc = self.Metafunc(func) metafunc = self.Metafunc(func)
pytest.raises(ValueError, "metafunc.addcall(id=None)") pytest.raises(ValueError, metafunc.addcall, id=None)
metafunc.addcall(id=1) metafunc.addcall(id=1)
pytest.raises(ValueError, "metafunc.addcall(id=1)") pytest.raises(ValueError, metafunc.addcall, id=1)
pytest.raises(ValueError, "metafunc.addcall(id='1')") pytest.raises(ValueError, metafunc.addcall, id="1")
metafunc.addcall(id=2) metafunc.addcall(id=2)
assert len(metafunc._calls) == 2 assert len(metafunc._calls) == 2
assert metafunc._calls[0].id == "1" assert metafunc._calls[0].id == "1"
@ -108,7 +108,7 @@ class TestMetafunc(object):
metafunc.addcall(funcargs={"x": 2}) metafunc.addcall(funcargs={"x": 2})
metafunc.addcall(funcargs={"x": 3}) metafunc.addcall(funcargs={"x": 3})
pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})") pytest.raises(pytest.fail.Exception, metafunc.addcall, {"xyz": 0})
assert len(metafunc._calls) == 2 assert len(metafunc._calls) == 2
assert metafunc._calls[0].funcargs == {"x": 2} assert metafunc._calls[0].funcargs == {"x": 2}
assert metafunc._calls[1].funcargs == {"x": 3} assert metafunc._calls[1].funcargs == {"x": 3}

View File

@ -4,25 +4,32 @@ import six
import pytest import pytest
from _pytest.outcomes import Failed from _pytest.outcomes import Failed
from _pytest.warning_types import PytestDeprecationWarning
class TestRaises(object): class TestRaises(object):
def test_raises(self): def test_raises(self):
source = "int('qwe')" source = "int('qwe')"
excinfo = pytest.raises(ValueError, source) with pytest.warns(PytestDeprecationWarning):
excinfo = pytest.raises(ValueError, source)
code = excinfo.traceback[-1].frame.code code = excinfo.traceback[-1].frame.code
s = str(code.fullsource) s = str(code.fullsource)
assert s == source assert s == source
def test_raises_exec(self): def test_raises_exec(self):
pytest.raises(ValueError, "a,x = []") with pytest.warns(PytestDeprecationWarning) as warninfo:
pytest.raises(ValueError, "a,x = []")
assert warninfo[0].filename == __file__
def test_raises_exec_correct_filename(self): def test_raises_exec_correct_filename(self):
excinfo = pytest.raises(ValueError, 'int("s")') with pytest.warns(PytestDeprecationWarning):
assert __file__ in excinfo.traceback[-1].path excinfo = pytest.raises(ValueError, 'int("s")')
assert __file__ in excinfo.traceback[-1].path
def test_raises_syntax_error(self): def test_raises_syntax_error(self):
pytest.raises(SyntaxError, "qwe qwe qwe") with pytest.warns(PytestDeprecationWarning) as warninfo:
pytest.raises(SyntaxError, "qwe qwe qwe")
assert warninfo[0].filename == __file__
def test_raises_function(self): def test_raises_function(self):
pytest.raises(ValueError, int, "hello") pytest.raises(ValueError, int, "hello")

View File

@ -87,7 +87,7 @@ class TestCaptureManager(object):
try: try:
capman = CaptureManager("fd") capman = CaptureManager("fd")
capman.start_global_capturing() capman.start_global_capturing()
pytest.raises(AssertionError, "capman.start_global_capturing()") pytest.raises(AssertionError, capman.start_global_capturing)
capman.stop_global_capturing() capman.stop_global_capturing()
finally: finally:
capouter.stop_capturing() capouter.stop_capturing()
@ -798,10 +798,10 @@ class TestCaptureIO(object):
f = capture.CaptureIO() f = capture.CaptureIO()
if sys.version_info >= (3, 0): if sys.version_info >= (3, 0):
f.write("\u00f6") f.write("\u00f6")
pytest.raises(TypeError, "f.write(bytes('hello', 'UTF-8'))") pytest.raises(TypeError, f.write, b"hello")
else: else:
f.write(text_type("\u00f6", "UTF-8")) f.write(u"\u00f6")
f.write("hello") # bytes f.write(b"hello")
s = f.getvalue() s = f.getvalue()
f.close() f.close()
assert isinstance(s, text_type) assert isinstance(s, text_type)
@ -1149,7 +1149,7 @@ class TestStdCapture(object):
print("XXX which indicates an error in the underlying capturing") print("XXX which indicates an error in the underlying capturing")
print("XXX mechanisms") print("XXX mechanisms")
with self.getcapture(): with self.getcapture():
pytest.raises(IOError, "sys.stdin.read()") pytest.raises(IOError, sys.stdin.read)
class TestStdCaptureFD(TestStdCapture): class TestStdCaptureFD(TestStdCapture):

View File

@ -194,7 +194,7 @@ class TestConfigAPI(object):
config = testdir.parseconfig("--hello=this") config = testdir.parseconfig("--hello=this")
for x in ("hello", "--hello", "-X"): for x in ("hello", "--hello", "-X"):
assert config.getoption(x) == "this" assert config.getoption(x) == "this"
pytest.raises(ValueError, "config.getoption('qweqwe')") pytest.raises(ValueError, config.getoption, "qweqwe")
@pytest.mark.skipif("sys.version_info[0] < 3") @pytest.mark.skipif("sys.version_info[0] < 3")
def test_config_getoption_unicode(self, testdir): def test_config_getoption_unicode(self, testdir):
@ -211,7 +211,7 @@ class TestConfigAPI(object):
def test_config_getvalueorskip(self, testdir): def test_config_getvalueorskip(self, testdir):
config = testdir.parseconfig() config = testdir.parseconfig()
pytest.raises(pytest.skip.Exception, "config.getvalueorskip('hello')") pytest.raises(pytest.skip.Exception, config.getvalueorskip, "hello")
verbose = config.getvalueorskip("verbose") verbose = config.getvalueorskip("verbose")
assert verbose == config.option.verbose assert verbose == config.option.verbose
@ -723,7 +723,8 @@ def test_config_in_subdirectory_colon_command_line_issue2148(testdir):
def test_notify_exception(testdir, capfd): def test_notify_exception(testdir, capfd):
config = testdir.parseconfig() config = testdir.parseconfig()
excinfo = pytest.raises(ValueError, "raise ValueError(1)") with pytest.raises(ValueError) as excinfo:
raise ValueError(1)
config.notify_exception(excinfo) config.notify_exception(excinfo)
out, err = capfd.readouterr() out, err = capfd.readouterr()
assert "ValueError" in err assert "ValueError" in err

View File

@ -27,7 +27,7 @@ def test_setattr():
x = 1 x = 1
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()
pytest.raises(AttributeError, "monkeypatch.setattr(A, 'notexists', 2)") pytest.raises(AttributeError, monkeypatch.setattr, A, "notexists", 2)
monkeypatch.setattr(A, "y", 2, raising=False) monkeypatch.setattr(A, "y", 2, raising=False)
assert A.y == 2 assert A.y == 2
monkeypatch.undo() monkeypatch.undo()
@ -99,7 +99,7 @@ def test_delattr():
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()
monkeypatch.delattr(A, "x") monkeypatch.delattr(A, "x")
pytest.raises(AttributeError, "monkeypatch.delattr(A, 'y')") pytest.raises(AttributeError, monkeypatch.delattr, A, "y")
monkeypatch.delattr(A, "y", raising=False) monkeypatch.delattr(A, "y", raising=False)
monkeypatch.setattr(A, "x", 5, raising=False) monkeypatch.setattr(A, "x", 5, raising=False)
assert A.x == 5 assert A.x == 5
@ -156,7 +156,7 @@ def test_delitem():
monkeypatch.delitem(d, "x") monkeypatch.delitem(d, "x")
assert "x" not in d assert "x" not in d
monkeypatch.delitem(d, "y", raising=False) monkeypatch.delitem(d, "y", raising=False)
pytest.raises(KeyError, "monkeypatch.delitem(d, 'y')") pytest.raises(KeyError, monkeypatch.delitem, d, "y")
assert not d assert not d
monkeypatch.setitem(d, "y", 1700) monkeypatch.setitem(d, "y", 1700)
assert d["y"] == 1700 assert d["y"] == 1700
@ -182,7 +182,7 @@ def test_delenv():
name = "xyz1234" name = "xyz1234"
assert name not in os.environ assert name not in os.environ
monkeypatch = MonkeyPatch() monkeypatch = MonkeyPatch()
pytest.raises(KeyError, "monkeypatch.delenv(%r, raising=True)" % name) pytest.raises(KeyError, monkeypatch.delenv, name, raising=True)
monkeypatch.delenv(name, raising=False) monkeypatch.delenv(name, raising=False)
monkeypatch.undo() monkeypatch.undo()
os.environ[name] = "1" os.environ[name] = "1"

View File

@ -100,12 +100,8 @@ class TestParser(object):
def test_group_shortopt_lowercase(self, parser): def test_group_shortopt_lowercase(self, parser):
group = parser.getgroup("hello") group = parser.getgroup("hello")
pytest.raises( with pytest.raises(ValueError):
ValueError,
"""
group.addoption("-x", action="store_true") group.addoption("-x", action="store_true")
""",
)
assert len(group.options) == 0 assert len(group.options) == 0
group._addoption("-x", action="store_true") group._addoption("-x", action="store_true")
assert len(group.options) == 1 assert len(group.options) == 1

View File

@ -196,7 +196,7 @@ class TestPytestPluginManager(object):
assert pm.is_registered(mod) assert pm.is_registered(mod)
values = pm.get_plugins() values = pm.get_plugins()
assert mod in values assert mod in values
pytest.raises(ValueError, "pm.register(mod)") pytest.raises(ValueError, pm.register, mod)
pytest.raises(ValueError, lambda: pm.register(mod)) pytest.raises(ValueError, lambda: pm.register(mod))
# assert not pm.is_registered(mod2) # assert not pm.is_registered(mod2)
assert pm.get_plugins() == values assert pm.get_plugins() == values
@ -284,8 +284,8 @@ class TestPytestPluginManager(object):
result.stdout.fnmatch_lines(["*1 passed*"]) result.stdout.fnmatch_lines(["*1 passed*"])
def test_import_plugin_importname(self, testdir, pytestpm): def test_import_plugin_importname(self, testdir, pytestpm):
pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")') pytest.raises(ImportError, pytestpm.import_plugin, "qweqwex.y")
pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwx.y")') pytest.raises(ImportError, pytestpm.import_plugin, "pytest_qweqwx.y")
testdir.syspathinsert() testdir.syspathinsert()
pluginname = "pytest_hello" pluginname = "pytest_hello"
@ -301,8 +301,8 @@ class TestPytestPluginManager(object):
assert plugin2 is plugin1 assert plugin2 is plugin1
def test_import_plugin_dotted_name(self, testdir, pytestpm): def test_import_plugin_dotted_name(self, testdir, pytestpm):
pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")') pytest.raises(ImportError, pytestpm.import_plugin, "qweqwex.y")
pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwex.y")') pytest.raises(ImportError, pytestpm.import_plugin, "pytest_qweqwex.y")
testdir.syspathinsert() testdir.syspathinsert()
testdir.mkpydir("pkg").join("plug.py").write("x=3") testdir.mkpydir("pkg").join("plug.py").write("x=3")

View File

@ -71,7 +71,7 @@ def test_make_hook_recorder(testdir):
recorder.unregister() recorder.unregister()
recorder.clear() recorder.clear()
recorder.hook.pytest_runtest_logreport(report=rep) recorder.hook.pytest_runtest_logreport(report=rep)
pytest.raises(ValueError, "recorder.getfailures()") pytest.raises(ValueError, recorder.getfailures)
def test_parseconfig(testdir): def test_parseconfig(testdir):
@ -174,7 +174,7 @@ def test_hookrecorder_basic(holder):
call = rec.popcall("pytest_xyz") call = rec.popcall("pytest_xyz")
assert call.arg == 123 assert call.arg == 123
assert call._name == "pytest_xyz" assert call._name == "pytest_xyz"
pytest.raises(pytest.fail.Exception, "rec.popcall('abc')") pytest.raises(pytest.fail.Exception, rec.popcall, "abc")
pm.hook.pytest_xyz_noarg() pm.hook.pytest_xyz_noarg()
call = rec.popcall("pytest_xyz_noarg") call = rec.popcall("pytest_xyz_noarg")
assert call._name == "pytest_xyz_noarg" assert call._name == "pytest_xyz_noarg"

View File

@ -7,6 +7,7 @@ import warnings
import pytest import pytest
from _pytest.recwarn import WarningsRecorder from _pytest.recwarn import WarningsRecorder
from _pytest.warning_types import PytestDeprecationWarning
def test_recwarn_stacklevel(recwarn): def test_recwarn_stacklevel(recwarn):
@ -44,7 +45,7 @@ class TestWarningsRecorderChecker(object):
rec.clear() rec.clear()
assert len(rec.list) == 0 assert len(rec.list) == 0
assert values is rec.list assert values is rec.list
pytest.raises(AssertionError, "rec.pop()") pytest.raises(AssertionError, rec.pop)
@pytest.mark.issue(4243) @pytest.mark.issue(4243)
def test_warn_stacklevel(self): def test_warn_stacklevel(self):
@ -214,9 +215,17 @@ class TestWarns(object):
source1 = "warnings.warn('w1', RuntimeWarning)" source1 = "warnings.warn('w1', RuntimeWarning)"
source2 = "warnings.warn('w2', RuntimeWarning)" source2 = "warnings.warn('w2', RuntimeWarning)"
source3 = "warnings.warn('w3', RuntimeWarning)" source3 = "warnings.warn('w3', RuntimeWarning)"
pytest.warns(RuntimeWarning, source1) with pytest.warns(PytestDeprecationWarning) as warninfo: # yo dawg
pytest.raises(pytest.fail.Exception, lambda: pytest.warns(UserWarning, source2)) pytest.warns(RuntimeWarning, source1)
pytest.warns(RuntimeWarning, source3) pytest.raises(
pytest.fail.Exception, lambda: pytest.warns(UserWarning, source2)
)
pytest.warns(RuntimeWarning, source3)
assert len(warninfo) == 3
for w in warninfo:
assert w.filename == __file__
msg, = w.message.args
assert msg.startswith("warns(..., 'code(as_a_string)') is deprecated")
def test_function(self): def test_function(self):
pytest.warns( pytest.warns(

View File

@ -700,17 +700,13 @@ def test_importorskip(monkeypatch):
# check that importorskip reports the actual call # check that importorskip reports the actual call
# in this test the test_runner.py file # in this test the test_runner.py file
assert path.purebasename == "test_runner" assert path.purebasename == "test_runner"
pytest.raises(SyntaxError, "pytest.importorskip('x y z')") pytest.raises(SyntaxError, pytest.importorskip, "x y z")
pytest.raises(SyntaxError, "pytest.importorskip('x=y')") pytest.raises(SyntaxError, pytest.importorskip, "x=y")
mod = types.ModuleType("hello123") mod = types.ModuleType("hello123")
mod.__version__ = "1.3" mod.__version__ = "1.3"
monkeypatch.setitem(sys.modules, "hello123", mod) monkeypatch.setitem(sys.modules, "hello123", mod)
pytest.raises( with pytest.raises(pytest.skip.Exception):
pytest.skip.Exception,
"""
pytest.importorskip("hello123", minversion="1.3.1") pytest.importorskip("hello123", minversion="1.3.1")
""",
)
mod2 = pytest.importorskip("hello123", minversion="1.3") mod2 = pytest.importorskip("hello123", minversion="1.3")
assert mod2 == mod assert mod2 == mod
except pytest.skip.Exception: except pytest.skip.Exception:
@ -730,11 +726,8 @@ def test_importorskip_dev_module(monkeypatch):
monkeypatch.setitem(sys.modules, "mockmodule", mod) monkeypatch.setitem(sys.modules, "mockmodule", mod)
mod2 = pytest.importorskip("mockmodule", minversion="0.12.0") mod2 = pytest.importorskip("mockmodule", minversion="0.12.0")
assert mod2 == mod assert mod2 == mod
pytest.raises( with pytest.raises(pytest.skip.Exception):
pytest.skip.Exception, pytest.importorskip("mockmodule1", minversion="0.14.0")
"""
pytest.importorskip('mockmodule1', minversion='0.14.0')""",
)
except pytest.skip.Exception: except pytest.skip.Exception:
print(_pytest._code.ExceptionInfo.from_current()) print(_pytest._code.ExceptionInfo.from_current())
pytest.fail("spurious skip") pytest.fail("spurious skip")

View File

@ -243,12 +243,8 @@ class TestNewSession(SessionTests):
def test_plugin_specify(testdir): def test_plugin_specify(testdir):
pytest.raises( with pytest.raises(ImportError):
ImportError, testdir.parseconfig("-p", "nqweotexistent")
"""
testdir.parseconfig("-p", "nqweotexistent")
""",
)
# pytest.raises(ImportError, # pytest.raises(ImportError,
# "config.do_configure(config)" # "config.do_configure(config)"
# ) # )

View File

@ -105,7 +105,8 @@ class TestTerminal(object):
def test_internalerror(self, testdir, linecomp): def test_internalerror(self, testdir, linecomp):
modcol = testdir.getmodulecol("def test_one(): pass") modcol = testdir.getmodulecol("def test_one(): pass")
rep = TerminalReporter(modcol.config, file=linecomp.stringio) rep = TerminalReporter(modcol.config, file=linecomp.stringio)
excinfo = pytest.raises(ValueError, "raise ValueError('hello')") with pytest.raises(ValueError) as excinfo:
raise ValueError("hello")
rep.pytest_internalerror(excinfo.getrepr()) rep.pytest_internalerror(excinfo.getrepr())
linecomp.assert_contains_lines(["INTERNALERROR> *ValueError*hello*"]) linecomp.assert_contains_lines(["INTERNALERROR> *ValueError*hello*"])