test_ok1/testing/test_assertion.py

258 lines
7.5 KiB
Python

import sys
import py, pytest
import _pytest.assertion as plugin
from _pytest.assertion import reinterpret, util
needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)")
def interpret(expr):
return reinterpret.reinterpret(expr, py.code.Frame(sys._getframe(1)))
class TestBinReprIntegration:
pytestmark = needsnewassert
def pytest_funcarg__hook(self, request):
class MockHook(object):
def __init__(self):
self.called = False
self.args = tuple()
self.kwargs = dict()
def __call__(self, op, left, right):
self.called = True
self.op = op
self.left = left
self.right = right
mockhook = MockHook()
monkeypatch = request.getfuncargvalue("monkeypatch")
monkeypatch.setattr(util, '_reprcompare', mockhook)
return mockhook
def test_pytest_assertrepr_compare_called(self, hook):
interpret('assert 0 == 1')
assert hook.called
def test_pytest_assertrepr_compare_args(self, hook):
interpret('assert [0, 1] == [0, 2]')
assert hook.op == '=='
assert hook.left == [0, 1]
assert hook.right == [0, 2]
def test_configure_unconfigure(self, testdir, hook):
assert hook == util._reprcompare
config = testdir.parseconfig()
plugin.pytest_configure(config)
assert hook != util._reprcompare
from _pytest.config import pytest_unconfigure
pytest_unconfigure(config)
assert hook == util._reprcompare
def callequal(left, right):
return plugin.pytest_assertrepr_compare('==', left, right)
class TestAssert_reprcompare:
def test_different_types(self):
assert callequal([0, 1], 'foo') is None
def test_summary(self):
summary = callequal([0, 1], [0, 2])[0]
assert len(summary) < 65
def test_text_diff(self):
diff = callequal('spam', 'eggs')[1:]
assert '- spam' in diff
assert '+ eggs' in diff
def test_multiline_text_diff(self):
left = 'foo\nspam\nbar'
right = 'foo\neggs\nbar'
diff = callequal(left, right)
assert '- spam' in diff
assert '+ eggs' in diff
def test_list(self):
expl = callequal([0, 1], [0, 2])
assert len(expl) > 1
def test_list_different_lenghts(self):
expl = callequal([0, 1], [0, 1, 2])
assert len(expl) > 1
expl = callequal([0, 1, 2], [0, 1])
assert len(expl) > 1
def test_dict(self):
expl = callequal({'a': 0}, {'a': 1})
assert len(expl) > 1
def test_set(self):
expl = callequal(set([0, 1]), set([0, 2]))
assert len(expl) > 1
def test_list_tuples(self):
expl = callequal([], [(1,2)])
assert len(expl) > 1
expl = callequal([(1,2)], [])
assert len(expl) > 1
def test_list_bad_repr(self):
class A:
def __repr__(self):
raise ValueError(42)
expl = callequal([], [A()])
assert 'ValueError' in "".join(expl)
expl = callequal({}, {'1': A()})
assert 'faulty' in "".join(expl)
def test_one_repr_empty(self):
"""
the faulty empty string repr did trigger
a unbound local error in _diff_text
"""
class A(str):
def __repr__(self):
return ''
expl = callequal(A(), '')
assert not expl
def test_repr_no_exc(self):
expl = ' '.join(callequal('foo', 'bar'))
assert 'raised in repr()' not in expl
@pytest.mark.skipif("config._assertstate.mode != 'on'")
def test_rewritten():
assert "@py_builtins" in globals()
def test_reprcompare_notin():
detail = plugin.pytest_assertrepr_compare('not in', 'foo', 'aaafoobbb')[1:]
assert detail == ["'foo' is contained here:", ' aaafoobbb', '? +++']
@needsnewassert
def test_pytest_assertrepr_compare_integration(testdir):
testdir.makepyfile("""
def test_hello():
x = set(range(100))
y = x.copy()
y.remove(50)
assert x == y
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines([
"*def test_hello():*",
"*assert x == y*",
"*E*Extra items*left*",
"*E*50*",
])
@needsnewassert
def test_sequence_comparison_uses_repr(testdir):
testdir.makepyfile("""
def test_hello():
x = set("hello x")
y = set("hello y")
assert x == y
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines([
"*def test_hello():*",
"*assert x == y*",
"*E*Extra items*left*",
"*E*'x'*",
"*E*Extra items*right*",
"*E*'y'*",
])
def test_assertion_options(testdir):
testdir.makepyfile("""
def test_hello():
x = 3
assert x == 4
""")
result = testdir.runpytest()
assert "3 == 4" in result.stdout.str()
off_options = (("--no-assert",),
("--nomagic",),
("--no-assert", "--nomagic"),
("--assertmode=off",),
("--assertmode=off", "--no-assert"),
("--assertmode=off", "--nomagic"),
("--assertmode=off," "--no-assert", "--nomagic"))
for opt in off_options:
result = testdir.runpytest(*opt)
assert "3 == 4" not in result.stdout.str()
for mode in "on", "old":
for other_opt in off_options[:3]:
opt = ("--assertmode=" + mode,) + other_opt
result = testdir.runpytest(*opt)
assert result.ret == 3
assert "assertion options conflict" in result.stderr.str()
def test_old_assert_mode(testdir):
testdir.makepyfile("""
def test_in_old_mode():
assert "@py_builtins" not in globals()
""")
result = testdir.runpytest("--assertmode=old")
assert result.ret == 0
def test_triple_quoted_string_issue113(testdir):
testdir.makepyfile("""
def test_hello():
assert "" == '''
'''""")
result = testdir.runpytest("--fulltrace")
result.stdout.fnmatch_lines([
"*1 failed*",
])
assert 'SyntaxError' not in result.stdout.str()
def test_traceback_failure(testdir):
p1 = testdir.makepyfile("""
def g():
return 2
def f(x):
assert x == g()
def test_onefails():
f(3)
""")
result = testdir.runpytest(p1)
result.stdout.fnmatch_lines([
"*test_traceback_failure.py F",
"====* FAILURES *====",
"____*____",
"",
" def test_onefails():",
"> f(3)",
"",
"*test_*.py:6: ",
"_ _ _ *",
#"",
" def f(x):",
"> assert x == g()",
"E assert 3 == 2",
"E + where 2 = g()",
"",
"*test_traceback_failure.py:4: AssertionError"
])
@pytest.mark.skipif("sys.version_info < (2,5) or '__pypy__' in sys.builtin_module_names")
def test_warn_missing(testdir):
p1 = testdir.makepyfile("")
result = testdir.run(sys.executable, "-OO", "-m", "pytest", "-h")
result.stderr.fnmatch_lines([
"*WARNING*assertion*",
])
result = testdir.run(sys.executable, "-OO", "-m", "pytest", "--no-assert")
result.stderr.fnmatch_lines([
"*WARNING*assertion*",
])
def test_load_fake_pyc(testdir):
path = testdir.makepyfile("x = 'hello'")
co = compile("x = 'bye'", str(path), "exec")
plugin._write_pyc(co, path)
mod = path.pyimport()
assert mod.x == "bye"