test_ok1/testing/test_assertrewrite.py

1139 lines
31 KiB
Python
Raw Normal View History

from __future__ import absolute_import, division, print_function
import glob
import os
import py_compile
import stat
import sys
2017-12-27 11:47:26 +08:00
import textwrap
import zipfile
import py
import pytest
import _pytest._code
from _pytest.assertion import util
2018-05-23 22:48:46 +08:00
from _pytest.assertion.rewrite import (
rewrite_asserts,
PYTEST_TAG,
AssertionRewritingHook,
)
from _pytest.main import EXIT_NOTESTSCOLLECTED
ast = pytest.importorskip("ast")
if sys.platform.startswith("java"):
# XXX should be xfail
pytest.skip("assert rewrite does currently not work on jython")
def setup_module(mod):
mod._old_reprcompare = util._reprcompare
_pytest._code._reprcompare = None
def teardown_module(mod):
util._reprcompare = mod._old_reprcompare
del mod._old_reprcompare
def rewrite(src):
tree = ast.parse(src)
rewrite_asserts(tree)
return tree
def getmsg(f, extra_ns=None, must_pass=False):
"""Rewrite the assertions in f, run it, and get the failure message."""
2018-05-23 22:48:46 +08:00
src = "\n".join(_pytest._code.Code(f).source().lines)
mod = rewrite(src)
code = compile(mod, "<test>", "exec")
ns = {}
if extra_ns is not None:
ns.update(extra_ns)
2011-05-25 07:28:05 +08:00
py.builtin.exec_(code, ns)
func = ns[f.__name__]
try:
func()
except AssertionError:
if must_pass:
pytest.fail("shouldn't have raised")
s = str(sys.exc_info()[1])
if not s.startswith("assert"):
return "AssertionError: " + s
return s
else:
if not must_pass:
pytest.fail("function didn't raise at all")
class TestAssertionRewrite(object):
def test_place_initial_imports(self):
2011-05-20 22:44:36 +08:00
s = """'Doc string'\nother = stuff"""
m = rewrite(s)
2017-11-04 02:37:18 +08:00
# Module docstrings in 3.7 are part of Module node, it's not in the body
# so we remove it so the following body items have the same indexes on
# all Python versions
if sys.version_info < (3, 7):
assert isinstance(m.body[0], ast.Expr)
assert isinstance(m.body[0].value, ast.Str)
del m.body[0]
for imp in m.body[0:2]:
assert isinstance(imp, ast.Import)
assert imp.lineno == 2
assert imp.col_offset == 0
2017-11-04 02:37:18 +08:00
assert isinstance(m.body[2], ast.Assign)
2011-05-20 22:44:36 +08:00
s = """from __future__ import with_statement\nother_stuff"""
m = rewrite(s)
assert isinstance(m.body[0], ast.ImportFrom)
for imp in m.body[1:3]:
assert isinstance(imp, ast.Import)
assert imp.lineno == 2
assert imp.col_offset == 0
assert isinstance(m.body[3], ast.Expr)
2017-11-04 02:37:18 +08:00
s = """'doc string'\nfrom __future__ import with_statement"""
m = rewrite(s)
if sys.version_info < (3, 7):
assert isinstance(m.body[0], ast.Expr)
assert isinstance(m.body[0].value, ast.Str)
del m.body[0]
assert isinstance(m.body[0], ast.ImportFrom)
for imp in m.body[1:3]:
assert isinstance(imp, ast.Import)
assert imp.lineno == 2
assert imp.col_offset == 0
2011-05-20 22:44:36 +08:00
s = """'doc string'\nfrom __future__ import with_statement\nother"""
m = rewrite(s)
2017-11-04 02:37:18 +08:00
if sys.version_info < (3, 7):
assert isinstance(m.body[0], ast.Expr)
assert isinstance(m.body[0].value, ast.Str)
del m.body[0]
assert isinstance(m.body[0], ast.ImportFrom)
for imp in m.body[1:3]:
assert isinstance(imp, ast.Import)
assert imp.lineno == 3
assert imp.col_offset == 0
2017-11-04 02:37:18 +08:00
assert isinstance(m.body[3], ast.Expr)
s = """from . import relative\nother_stuff"""
m = rewrite(s)
for imp in m.body[0:2]:
assert isinstance(imp, ast.Import)
assert imp.lineno == 1
assert imp.col_offset == 0
assert isinstance(m.body[3], ast.Expr)
def test_dont_rewrite(self):
s = """'PYTEST_DONT_REWRITE'\nassert 14"""
m = rewrite(s)
2017-11-04 02:37:18 +08:00
if sys.version_info < (3, 7):
assert len(m.body) == 2
assert isinstance(m.body[0], ast.Expr)
assert isinstance(m.body[0].value, ast.Str)
del m.body[0]
else:
assert len(m.body) == 1
assert m.body[0].msg is None
def test_dont_rewrite_plugin(self, testdir):
contents = {
"conftest.py": "pytest_plugins = 'plugin'; import plugin",
"plugin.py": "'PYTEST_DONT_REWRITE'",
"test_foo.py": "def test_foo(): pass",
}
testdir.makepyfile(**contents)
result = testdir.runpytest_subprocess()
assert "warnings" not in "".join(result.outlines)
def test_name(self):
2018-05-23 22:48:46 +08:00
def f():
assert False
2018-05-23 22:48:46 +08:00
assert getmsg(f) == "assert False"
def f():
f = False
assert f
assert getmsg(f) == "assert False"
def f():
assert a_global # noqa
assert getmsg(f, {"a_global": False}) == "assert False"
def f():
assert sys == 42
assert getmsg(f, {"sys": sys}) == "assert sys == 42"
def f():
assert cls == 42 # noqa
class X(object):
pass
assert getmsg(f, {"cls": X}) == "assert cls == 42"
def test_assert_already_has_message(self):
2018-05-23 22:48:46 +08:00
def f():
assert False, "something bad!"
2018-05-23 22:48:46 +08:00
assert getmsg(f) == "AssertionError: something bad!\nassert False"
def test_assertion_message(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_foo():
assert 1 == 2, "The failure message"
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 1
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(
["*AssertionError*The failure message*", "*assert 1 == 2*"]
)
def test_assertion_message_multiline(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_foo():
assert 1 == 2, "A multiline\\nfailure message"
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 1
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(
["*AssertionError*A multiline*", "*failure message*", "*assert 1 == 2*"]
)
def test_assertion_message_tuple(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_foo():
assert 1 == 2, (1, 2)
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 1
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(
["*AssertionError*%s*" % repr((1, 2)), "*assert 1 == 2*"]
)
def test_assertion_message_expr(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_foo():
assert 1 == 2, 1 + 2
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 1
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["*AssertionError*3*", "*assert 1 == 2*"])
def test_assertion_message_escape(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_foo():
assert 1 == 2, 'To be escaped: %'
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 1
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(
["*AssertionError: To be escaped: %", "*assert 1 == 2"]
)
def test_boolop(self):
2018-05-23 22:48:46 +08:00
def f():
f = g = False
assert f and g
assert getmsg(f) == "assert (False)"
def f():
f = True
g = False
assert f and g
assert getmsg(f) == "assert (True and False)"
def f():
f = False
g = True
assert f and g
assert getmsg(f) == "assert (False)"
def f():
f = g = False
assert f or g
assert getmsg(f) == "assert (False or False)"
def f():
f = g = False
assert not f and not g
getmsg(f, must_pass=True)
def x():
return False
def f():
assert x() and x()
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, {"x": x})
== """assert (False)
+ where False = x()"""
2018-05-23 22:48:46 +08:00
)
def f():
assert False or x()
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, {"x": x})
== """assert (False or False)
+ where False = x()"""
2018-05-23 22:48:46 +08:00
)
def f():
assert 1 in {} and 2 in {}
assert getmsg(f) == "assert (1 in {})"
def f():
x = 1
y = 2
assert x in {1: None} and y in {}
assert getmsg(f) == "assert (1 in {1: None} and 2 in {})"
def f():
f = True
g = False
assert f or g
getmsg(f, must_pass=True)
2011-07-11 17:57:47 +08:00
def f():
f = g = h = lambda: True
assert f() and g() and h()
2011-07-11 17:57:47 +08:00
getmsg(f, must_pass=True)
2017-02-15 23:00:18 +08:00
def test_short_circuit_evaluation(self):
2018-05-23 22:48:46 +08:00
def f():
assert True or explode # noqa
getmsg(f, must_pass=True)
def f():
x = 1
assert x == 1 or x == 2
getmsg(f, must_pass=True)
def test_unary_op(self):
2018-05-23 22:48:46 +08:00
def f():
x = True
assert not x
assert getmsg(f) == "assert not True"
def f():
x = 0
assert ~x + 1
assert getmsg(f) == "assert (~0 + 1)"
def f():
x = 3
assert -x + x
assert getmsg(f) == "assert (-3 + 3)"
def f():
x = 0
assert +x + x
assert getmsg(f) == "assert (+0 + 0)"
def test_binary_op(self):
2018-05-23 22:48:46 +08:00
def f():
x = 1
y = -1
assert x + y
assert getmsg(f) == "assert (1 + -1)"
def f():
assert not 5 % 4
2018-05-23 22:48:46 +08:00
assert getmsg(f) == "assert not (5 % 4)"
def test_boolop_percent(self):
2018-05-23 22:48:46 +08:00
def f():
assert 3 % 2 and False
assert getmsg(f) == "assert ((3 % 2) and False)"
def f():
assert False or 4 % 2
2018-05-23 22:48:46 +08:00
assert getmsg(f) == "assert (False or (4 % 2))"
@pytest.mark.skipif("sys.version_info < (3,5)")
def test_at_operator_issue1290(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
class Matrix(object):
def __init__(self, num):
self.num = num
def __matmul__(self, other):
return self.num * other.num
def test_multmat_operator():
2018-05-23 22:48:46 +08:00
assert Matrix(2) @ Matrix(3) == 6"""
)
testdir.runpytest().assert_outcomes(passed=1)
def test_call(self):
2018-05-23 22:48:46 +08:00
def g(a=42, *args, **kwargs):
return False
ns = {"g": g}
def f():
assert g()
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g()"""
2018-05-23 22:48:46 +08:00
)
def f():
assert g(1)
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(1)"""
2018-05-23 22:48:46 +08:00
)
def f():
assert g(1, 2)
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(1, 2)"""
2018-05-23 22:48:46 +08:00
)
def f():
assert g(1, g=42)
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(1, g=42)"""
2018-05-23 22:48:46 +08:00
)
def f():
assert g(1, 3, g=23)
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(1, 3, g=23)"""
2018-05-23 22:48:46 +08:00
)
2011-07-15 00:46:32 +08:00
def f():
seq = [1, 2, 3]
assert g(*seq)
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(*[1, 2, 3])"""
2018-05-23 22:48:46 +08:00
)
def f():
x = "a"
assert g(**{x: 2})
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = g(**{'a': 2})"""
2018-05-23 22:48:46 +08:00
)
def test_attribute(self):
2018-05-23 22:48:46 +08:00
class X(object):
g = 3
ns = {"x": X}
def f():
assert not x.g # noqa
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert not 3
+ where 3 = x.g"""
2018-05-23 22:48:46 +08:00
)
def f():
x.a = False # noqa
2018-05-23 22:48:46 +08:00
assert x.a # noqa
2018-05-23 22:48:46 +08:00
assert (
getmsg(f, ns)
== """assert False
+ where False = x.a"""
2018-05-23 22:48:46 +08:00
)
def test_comparisons(self):
def f():
a, b = range(2)
assert b < a
assert getmsg(f) == """assert 1 < 0"""
def f():
a, b, c = range(3)
assert a > b > c
assert getmsg(f) == """assert 0 > 1"""
def f():
a, b, c = range(3)
assert a < b > c
assert getmsg(f) == """assert 1 > 2"""
def f():
a, b, c = range(3)
assert a < b <= c
getmsg(f, must_pass=True)
2011-05-20 07:56:48 +08:00
def f():
a, b, c = range(3)
assert a < b
assert b < c
2011-05-20 07:56:48 +08:00
getmsg(f, must_pass=True)
def test_len(self):
def f():
values = list(range(10))
assert len(values) == 11
2018-05-23 22:48:46 +08:00
assert getmsg(f).startswith(
"""assert 10 == 11
+ where 10 = len(["""
)
def test_custom_reprcompare(self, monkeypatch):
2018-05-23 22:48:46 +08:00
def my_reprcompare(op, left, right):
return "42"
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
def f():
assert 42 < 3
assert getmsg(f) == "assert 42"
def my_reprcompare(op, left, right):
return "%s %s %s" % (left, op, right)
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
def f():
assert 1 < 3 < 5 <= 4 < 7
assert getmsg(f) == "assert 5 <= 4"
def test_assert_raising_nonzero_in_comparison(self):
2018-05-23 22:48:46 +08:00
def f():
2018-05-23 22:48:46 +08:00
class A(object):
def __nonzero__(self):
raise ValueError(42)
def __lt__(self, other):
return A()
def __repr__(self):
return "<MY42 object>"
def myany(x):
return False
assert myany(A() < 0)
assert "<MY42 object> < 0" in getmsg(f)
def test_formatchar(self):
2018-05-23 22:48:46 +08:00
def f():
assert "%test" == "test"
assert getmsg(f).startswith("assert '%test' == 'test'")
def test_custom_repr(self):
2018-05-23 22:48:46 +08:00
def f():
2018-05-23 22:48:46 +08:00
class Foo(object):
a = 1
def __repr__(self):
return "\n{ \n~ \n}"
f = Foo()
assert 0 == f.a
assert r"where 1 = \n{ \n~ \n}.a" in util._format_lines([getmsg(f)])[0]
class TestRewriteOnImport(object):
def test_pycache_is_a_file(self, testdir):
testdir.tmpdir.join("__pycache__").write("Hello")
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
assert testdir.runpytest().ret == 0
def test_pycache_is_readonly(self, testdir):
cache = testdir.tmpdir.mkdir("__pycache__")
old_mode = cache.stat().mode
cache.chmod(old_mode ^ stat.S_IWRITE)
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
try:
assert testdir.runpytest().ret == 0
finally:
cache.chmod(old_mode)
def test_zipfile(self, testdir):
z = testdir.tmpdir.join("myzip.zip")
z_fn = str(z)
f = zipfile.ZipFile(z_fn, "w")
try:
f.writestr("test_gum/__init__.py", "")
f.writestr("test_gum/test_lizard.py", "")
finally:
f.close()
z.chmod(256)
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
import sys
sys.path.append(%r)
2018-05-23 22:48:46 +08:00
import test_gum.test_lizard"""
% (z_fn,)
)
assert testdir.runpytest().ret == EXIT_NOTESTSCOLLECTED
def test_readonly(self, testdir):
sub = testdir.mkdir("testing")
2011-07-20 11:56:34 +08:00
sub.join("test_readonly.py").write(
2018-05-23 22:48:46 +08:00
py.builtin._totext(
"""
def test_rewritten():
2011-07-20 11:41:58 +08:00
assert "@py_builtins" in globals()
2018-05-23 22:48:46 +08:00
"""
).encode(
"utf-8"
),
"wb",
)
old_mode = sub.stat().mode
sub.chmod(320)
try:
assert testdir.runpytest().ret == 0
finally:
sub.chmod(old_mode)
def test_dont_write_bytecode(self, testdir, monkeypatch):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
import os
def test_no_bytecode():
assert "__pycache__" in __cached__
assert not os.path.exists(__cached__)
2018-05-23 22:48:46 +08:00
assert not os.path.exists(os.path.dirname(__cached__))"""
)
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
assert testdir.runpytest_subprocess().ret == 0
def test_orphaned_pyc_file(self, testdir):
2018-05-23 22:48:46 +08:00
if sys.version_info < (3, 0) and hasattr(sys, "pypy_version_info"):
pytest.skip("pypy2 doesn't run orphaned pyc files")
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
import orphan
def test_it():
assert orphan.value == 17
2018-05-23 22:48:46 +08:00
"""
)
testdir.makepyfile(
orphan="""
value = 17
2018-05-23 22:48:46 +08:00
"""
)
py_compile.compile("orphan.py")
os.remove("orphan.py")
# Python 3 puts the .pyc files in a __pycache__ directory, and will
# not import from there without source. It will import a .pyc from
# the source location though.
if not os.path.exists("orphan.pyc"):
pycs = glob.glob("__pycache__/orphan.*.pyc")
assert len(pycs) == 1
os.rename(pycs[0], "orphan.pyc")
assert testdir.runpytest().ret == 0
@pytest.mark.skipif('"__pypy__" in sys.modules')
def test_pyc_vs_pyo(self, testdir, monkeypatch):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
import pytest
def test_optimized():
"hello"
assert test_optimized.__doc__ is None"""
2018-05-23 22:48:46 +08:00
)
p = py.path.local.make_numbered_dir(
prefix="runpytest-", keep=None, rootdir=testdir.tmpdir
)
tmp = "--basetemp=%s" % p
monkeypatch.setenv("PYTHONOPTIMIZE", "2")
monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)
assert testdir.runpytest_subprocess(tmp).ret == 0
2012-07-07 23:01:44 +08:00
tagged = "test_pyc_vs_pyo." + PYTEST_TAG
assert tagged + ".pyo" in os.listdir("__pycache__")
monkeypatch.undo()
monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)
assert testdir.runpytest_subprocess(tmp).ret == 1
2012-07-07 23:01:44 +08:00
assert tagged + ".pyc" in os.listdir("__pycache__")
def test_package(self, testdir):
pkg = testdir.tmpdir.join("pkg")
pkg.mkdir()
pkg.join("__init__.py").ensure()
2018-05-23 22:48:46 +08:00
pkg.join("test_blah.py").write(
"""
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
assert testdir.runpytest().ret == 0
def test_translate_newlines(self, testdir):
content = "def test_rewritten():\r\n assert '@py_builtins' in globals()"
b = content.encode("utf-8")
testdir.tmpdir.join("test_newlines.py").write(b, "wb")
assert testdir.runpytest().ret == 0
2018-05-23 22:48:46 +08:00
@pytest.mark.skipif(
sys.version_info < (3, 4),
reason="packages without __init__.py not supported on python 2",
)
def test_package_without__init__py(self, testdir):
2018-05-23 22:48:46 +08:00
pkg = testdir.mkdir("a_package_without_init_py")
pkg.join("module.py").ensure()
testdir.makepyfile("import a_package_without_init_py.module")
assert testdir.runpytest().ret == EXIT_NOTESTSCOLLECTED
def test_rewrite_warning(self, pytestconfig, monkeypatch):
hook = AssertionRewritingHook(pytestconfig)
warnings = []
def mywarn(code, msg):
warnings.append((code, msg))
2018-05-23 22:48:46 +08:00
monkeypatch.setattr(hook.config, "warn", mywarn)
hook.mark_rewrite("_pytest")
assert "_pytest" in warnings[0][1]
def test_rewrite_module_imported_from_conftest(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makeconftest(
"""
import test_rewrite_module_imported
2018-05-23 22:48:46 +08:00
"""
)
testdir.makepyfile(
test_rewrite_module_imported="""
def test_rewritten():
assert "@py_builtins" in globals()
2018-05-23 22:48:46 +08:00
"""
)
assert testdir.runpytest_subprocess().ret == 0
def test_remember_rewritten_modules(self, pytestconfig, testdir, monkeypatch):
"""
AssertionRewriteHook should remember rewritten modules so it
doesn't give false positives (#2005).
"""
monkeypatch.syspath_prepend(testdir.tmpdir)
2018-05-23 22:48:46 +08:00
testdir.makepyfile(test_remember_rewritten_modules="")
warnings = []
hook = AssertionRewritingHook(pytestconfig)
2018-05-23 22:48:46 +08:00
monkeypatch.setattr(hook.config, "warn", lambda code, msg: warnings.append(msg))
hook.find_module("test_remember_rewritten_modules")
hook.load_module("test_remember_rewritten_modules")
hook.mark_rewrite("test_remember_rewritten_modules")
hook.mark_rewrite("test_remember_rewritten_modules")
assert warnings == []
def test_rewrite_warning_using_pytest_plugins(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
**{
"conftest.py": "pytest_plugins = ['core', 'gui', 'sci']",
"core.py": "",
"gui.py": "pytest_plugins = ['core', 'sci']",
"sci.py": "pytest_plugins = ['core']",
"test_rewrite_warning_pytest_plugins.py": "def test(): pass",
}
)
testdir.chdir()
result = testdir.runpytest_subprocess()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["*= 1 passed in *=*"])
assert "pytest-warning summary" not in result.stdout.str()
def test_rewrite_warning_using_pytest_plugins_env_var(self, testdir, monkeypatch):
2018-05-23 22:48:46 +08:00
monkeypatch.setenv("PYTEST_PLUGINS", "plugin")
testdir.makepyfile(
**{
"plugin.py": "",
"test_rewrite_warning_using_pytest_plugins_env_var.py": """
import plugin
pytest_plugins = ['plugin']
def test():
pass
""",
2018-05-23 22:48:46 +08:00
}
)
testdir.chdir()
result = testdir.runpytest_subprocess()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["*= 1 passed in *=*"])
assert "pytest-warning summary" not in result.stdout.str()
2018-05-23 22:48:46 +08:00
@pytest.mark.skipif(sys.version_info[0] > 2, reason="python 2 only")
def test_rewrite_future_imports(self, testdir):
"""Test that rewritten modules don't inherit the __future__ flags
from the assertrewrite module.
assertion.rewrite imports __future__.division (and others), so
ensure rewritten modules don't inherit those flags.
The test below will fail if __future__.division is enabled
"""
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test():
x = 1 / 2
assert type(x) is int
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
assert result.ret == 0
class TestAssertionRewriteHookDetails(object):
2018-05-23 22:48:46 +08:00
def test_loader_is_package_false_for_module(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_fun="""
def test_loader():
assert not __loader__.is_package(__name__)
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["* 1 passed*"])
def test_loader_is_package_true_for_package(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_fun="""
def test_loader():
assert not __loader__.is_package(__name__)
def test_fun():
assert __loader__.is_package('fun')
def test_missing():
assert not __loader__.is_package('pytest_not_there')
2018-05-23 22:48:46 +08:00
"""
)
testdir.mkpydir("fun")
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines(["* 3 passed*"])
@pytest.mark.skipif("sys.version_info[0] >= 3")
@pytest.mark.xfail("hasattr(sys, 'pypy_translation_info')")
def test_assume_ascii(self, testdir):
content = "u'\xe2\x99\xa5\x01\xfe'"
testdir.tmpdir.join("test_encoding.py").write(content, "wb")
res = testdir.runpytest()
assert res.ret != 0
assert "SyntaxError: Non-ASCII character" in res.stdout.str()
2013-10-06 03:03:04 +08:00
@pytest.mark.skipif("sys.version_info[0] >= 3")
def test_detect_coding_cookie(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_cookie="""
# -*- coding: utf-8 -*-
u"St\xc3\xa4d"
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
assert testdir.runpytest().ret == 0
@pytest.mark.skipif("sys.version_info[0] >= 3")
def test_detect_coding_cookie_second_line(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_cookie="""
# -*- coding: utf-8 -*-
u"St\xc3\xa4d"
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
2013-10-06 03:03:04 +08:00
assert testdir.runpytest().ret == 0
@pytest.mark.skipif("sys.version_info[0] >= 3")
def test_detect_coding_cookie_crlf(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_cookie="""
# -*- coding: utf-8 -*-
u"St\xc3\xa4d"
def test_rewritten():
2018-05-23 22:48:46 +08:00
assert "@py_builtins" in globals()"""
)
assert testdir.runpytest().ret == 0
def test_sys_meta_path_munged(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_meta_path():
2018-05-23 22:48:46 +08:00
import sys; sys.meta_path = []"""
)
assert testdir.runpytest().ret == 0
def test_write_pyc(self, testdir, tmpdir, monkeypatch):
from _pytest.assertion.rewrite import _write_pyc
from _pytest.assertion import AssertionState
import atomicwrites
from contextlib import contextmanager
2018-05-23 22:48:46 +08:00
config = testdir.parseconfig([])
state = AssertionState(config, "rewrite")
source_path = tmpdir.ensure("source.py")
pycpath = tmpdir.join("pyc").strpath
assert _write_pyc(state, [1], source_path.stat(), pycpath)
@contextmanager
2018-05-23 22:48:46 +08:00
def atomic_write_failed(fn, mode="r", overwrite=False):
e = IOError()
e.errno = 10
raise e
yield # noqa
monkeypatch.setattr(atomicwrites, "atomic_write", atomic_write_failed)
assert not _write_pyc(state, [1], source_path.stat(), pycpath)
def test_resources_provider_for_loader(self, testdir):
"""
Attempts to load resources from a package should succeed normally,
even when the AssertionRewriteHook is used to load the modules.
See #366 for details.
"""
pytest.importorskip("pkg_resources")
2018-05-23 22:48:46 +08:00
testdir.mkpydir("testpkg")
contents = {
2018-05-23 22:48:46 +08:00
"testpkg/test_pkg": """
import pkg_resources
import pytest
from _pytest.assertion.rewrite import AssertionRewritingHook
def test_load_resource():
assert isinstance(__loader__, AssertionRewritingHook)
res = pkg_resources.resource_string(__name__, 'resource.txt')
res = res.decode('ascii')
assert res == 'Load me please.'
2018-05-23 22:48:46 +08:00
"""
}
testdir.makepyfile(**contents)
2018-05-23 22:48:46 +08:00
testdir.maketxtfile(**{"testpkg/resource": "Load me please."})
result = testdir.runpytest_subprocess()
result.assert_outcomes(passed=1)
def test_read_pyc(self, tmpdir):
"""
Ensure that the `_read_pyc` can properly deal with corrupted pyc files.
In those circumstances it should just give up instead of generating
an exception that is propagated to the caller.
"""
import py_compile
from _pytest.assertion.rewrite import _read_pyc
2018-05-23 22:48:46 +08:00
source = tmpdir.join("source.py")
pyc = source + "c"
2018-05-23 22:48:46 +08:00
source.write("def test(): pass")
py_compile.compile(str(source), str(pyc))
2018-05-23 22:48:46 +08:00
contents = pyc.read(mode="rb")
strip_bytes = 20 # header is around 8 bytes, strip a little more
assert len(contents) > strip_bytes
2018-05-23 22:48:46 +08:00
pyc.write(contents[:strip_bytes], mode="wb")
assert _read_pyc(source, str(pyc)) is None # no error
def test_reload_is_same(self, testdir):
# A file that will be picked up during collecting.
testdir.tmpdir.join("file.py").ensure()
2018-05-23 22:48:46 +08:00
testdir.tmpdir.join("pytest.ini").write(
textwrap.dedent(
"""
[pytest]
python_files = *.py
2018-05-23 22:48:46 +08:00
"""
)
)
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
test_fun="""
import sys
try:
from imp import reload
except ImportError:
pass
def test_loader():
import file
assert sys.modules["file"] is reload(file)
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines(["* 1 passed*"])
def test_get_data_support(self, testdir):
"""Implement optional PEP302 api (#808).
"""
path = testdir.mkpydir("foo")
2018-05-23 22:48:46 +08:00
path.join("test_foo.py").write(
_pytest._code.Source(
"""
class Test(object):
def test_foo(self):
import pkgutil
data = pkgutil.get_data('foo.test_foo', 'data.txt')
assert data == b'Hey'
2018-05-23 22:48:46 +08:00
"""
)
)
path.join("data.txt").write("Hey")
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines("*1 passed*")
def test_issue731(testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
class LongReprWithBraces(object):
def __repr__(self):
return 'LongReprWithBraces({' + ('a' * 80) + '}' + ('a' * 120) + ')'
def some_method(self):
return False
def test_long_repr():
obj = LongReprWithBraces()
assert obj.some_method()
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
assert "unbalanced braces" not in result.stdout.str()
class TestIssue925(object):
2018-05-23 22:48:46 +08:00
def test_simple_case(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_ternary_display():
assert (False == False) == False
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines("*E*assert (False == False) == False")
def test_long_case(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_ternary_display():
assert False == (False == True) == True
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines("*E*assert (False == True) == True")
def test_many_brackets(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.makepyfile(
"""
def test_ternary_display():
assert True == ((False == True) == True)
2018-05-23 22:48:46 +08:00
"""
)
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines("*E*assert True == ((False == True) == True)")
2016-12-16 22:29:08 +08:00
class TestIssue2121():
2018-05-23 22:48:46 +08:00
2016-12-16 22:29:08 +08:00
def test_simple(self, testdir):
2018-05-23 22:48:46 +08:00
testdir.tmpdir.join("tests/file.py").ensure().write(
"""
2016-12-16 22:29:08 +08:00
def test_simple_failure():
assert 1 + 1 == 3
2018-05-23 22:48:46 +08:00
"""
)
testdir.tmpdir.join("pytest.ini").write(
textwrap.dedent(
"""
2016-12-16 22:29:08 +08:00
[pytest]
python_files = tests/**.py
2018-05-23 22:48:46 +08:00
"""
)
)
2016-12-16 22:29:08 +08:00
result = testdir.runpytest()
2018-05-23 22:48:46 +08:00
result.stdout.fnmatch_lines("*E*assert (1 + 1) == 3")