make py lib a self-contained directory again
- move and merge _py/ bits back to py/ - fixes all around --HG-- branch : trunk
This commit is contained in:
1
testing/plugin/__init__.py
Normal file
1
testing/plugin/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
#
|
||||
37
testing/plugin/conftest.py
Normal file
37
testing/plugin/conftest.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import py
|
||||
|
||||
pytest_plugins = "pytester"
|
||||
import py.plugin
|
||||
plugindir = py.path.local(py.plugin.__file__).dirpath()
|
||||
from py.impl.test.defaultconftest import pytest_plugins as default_plugins
|
||||
|
||||
def pytest_collect_file(path, parent):
|
||||
if path.basename.startswith("pytest_") and path.ext == ".py":
|
||||
mod = parent.Module(path, parent=parent)
|
||||
return mod
|
||||
|
||||
# for plugin test we try to automatically make sure that
|
||||
# the according plugin is loaded
|
||||
def pytest_funcarg__testdir(request):
|
||||
testdir = request.getfuncargvalue("testdir")
|
||||
#for obj in (request.cls, request.module):
|
||||
# if hasattr(obj, 'testplugin'):
|
||||
# testdir.plugins.append(obj.testplugin)
|
||||
# break
|
||||
#else:
|
||||
modname = request.module.__name__.split(".")[-1]
|
||||
if modname.startswith("test_pytest_"):
|
||||
modname = modname[5:]
|
||||
if plugindir.join("%s.py" % modname).check():
|
||||
if modname[7:] not in default_plugins:
|
||||
testdir.plugins.append(vars(request.module))
|
||||
testdir.plugins.append(modname)
|
||||
#elif modname.startswith("test_pytest"):
|
||||
# pname = modname[5:]
|
||||
# assert pname not in testdir.plugins
|
||||
# testdir.plugins.append(pname)
|
||||
# #testdir.plugins.append(vars(request.module))
|
||||
else:
|
||||
pass # raise ValueError("need better support code")
|
||||
return testdir
|
||||
|
||||
50
testing/plugin/test_pytest__pytest.py
Normal file
50
testing/plugin/test_pytest__pytest.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import py
|
||||
from py.plugin.pytest__pytest import HookRecorder
|
||||
|
||||
def test_hookrecorder_basic():
|
||||
comregistry = py._com.Registry()
|
||||
rec = HookRecorder(comregistry)
|
||||
class ApiClass:
|
||||
def xyz(self, arg):
|
||||
pass
|
||||
rec.start_recording(ApiClass)
|
||||
rec.hook.xyz(arg=123)
|
||||
call = rec.popcall("xyz")
|
||||
assert call.arg == 123
|
||||
assert call._name == "xyz"
|
||||
py.test.raises(ValueError, "rec.popcall('abc')")
|
||||
|
||||
def test_hookrecorder_basic_no_args_hook():
|
||||
import sys
|
||||
comregistry = py._com.Registry()
|
||||
rec = HookRecorder(comregistry)
|
||||
apimod = type(sys)('api')
|
||||
def xyz():
|
||||
pass
|
||||
apimod.xyz = xyz
|
||||
rec.start_recording(apimod)
|
||||
rec.hook.xyz()
|
||||
call = rec.popcall("xyz")
|
||||
assert call._name == "xyz"
|
||||
|
||||
reg = py._com.comregistry
|
||||
def test_functional_default(testdir, _pytest):
|
||||
assert _pytest.comregistry == py._com.comregistry
|
||||
assert _pytest.comregistry != reg
|
||||
|
||||
def test_functional(testdir, linecomp):
|
||||
reprec = testdir.inline_runsource("""
|
||||
import py
|
||||
pytest_plugins="_pytest"
|
||||
def test_func(_pytest):
|
||||
class ApiClass:
|
||||
def xyz(self, arg): pass
|
||||
rec = _pytest.gethookrecorder(ApiClass)
|
||||
class Plugin:
|
||||
def xyz(self, arg):
|
||||
return arg + 1
|
||||
rec._comregistry.register(Plugin())
|
||||
res = rec.hook.xyz(arg=41)
|
||||
assert res == [42]
|
||||
""")
|
||||
reprec.assertoutcome(passed=1)
|
||||
40
testing/plugin/test_pytest_assertion.py
Normal file
40
testing/plugin/test_pytest_assertion.py
Normal file
@@ -0,0 +1,40 @@
|
||||
def test_functional(testdir):
|
||||
testdir.makepyfile("""
|
||||
def test_hello():
|
||||
x = 3
|
||||
assert x == 4
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert "3 == 4" in result.stdout.str()
|
||||
result = testdir.runpytest("--no-assert")
|
||||
assert "3 == 4" 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"
|
||||
])
|
||||
|
||||
381
testing/plugin/test_pytest_capture.py
Normal file
381
testing/plugin/test_pytest_capture.py
Normal file
@@ -0,0 +1,381 @@
|
||||
import py, os, sys
|
||||
from py.plugin.pytest_capture import CaptureManager
|
||||
|
||||
needsosdup = py.test.mark.xfail("not hasattr(os, 'dup')")
|
||||
|
||||
class TestCaptureManager:
|
||||
def test_getmethod_default_no_fd(self, testdir, monkeypatch):
|
||||
config = testdir.parseconfig(testdir.tmpdir)
|
||||
assert config.getvalue("capture") is None
|
||||
capman = CaptureManager()
|
||||
monkeypatch.delattr(os, 'dup', raising=False)
|
||||
try:
|
||||
assert capman._getmethod(config, None) == "sys"
|
||||
finally:
|
||||
monkeypatch.undo()
|
||||
|
||||
def test_configure_per_fspath(self, testdir):
|
||||
config = testdir.parseconfig(testdir.tmpdir)
|
||||
assert config.getvalue("capture") is None
|
||||
capman = CaptureManager()
|
||||
hasfd = hasattr(os, 'dup')
|
||||
if hasfd:
|
||||
assert capman._getmethod(config, None) == "fd"
|
||||
else:
|
||||
assert capman._getmethod(config, None) == "sys"
|
||||
|
||||
for name in ('no', 'fd', 'sys'):
|
||||
if not hasfd and name == 'fd':
|
||||
continue
|
||||
sub = testdir.tmpdir.mkdir("dir" + name)
|
||||
sub.ensure("__init__.py")
|
||||
sub.join("conftest.py").write('option_capture = %r' % name)
|
||||
assert capman._getmethod(config, sub.join("test_hello.py")) == name
|
||||
|
||||
@needsosdup
|
||||
@py.test.mark.multi(method=['no', 'fd', 'sys'])
|
||||
def test_capturing_basic_api(self, method):
|
||||
capouter = py.io.StdCaptureFD()
|
||||
old = sys.stdout, sys.stderr, sys.stdin
|
||||
try:
|
||||
capman = CaptureManager()
|
||||
capman.resumecapture(method)
|
||||
print ("hello")
|
||||
out, err = capman.suspendcapture()
|
||||
if method == "no":
|
||||
assert old == (sys.stdout, sys.stderr, sys.stdin)
|
||||
else:
|
||||
assert out == "hello\n"
|
||||
capman.resumecapture(method)
|
||||
out, err = capman.suspendcapture()
|
||||
assert not out and not err
|
||||
finally:
|
||||
capouter.reset()
|
||||
|
||||
@needsosdup
|
||||
def test_juggle_capturings(self, testdir):
|
||||
capouter = py.io.StdCaptureFD()
|
||||
try:
|
||||
config = testdir.parseconfig(testdir.tmpdir)
|
||||
capman = CaptureManager()
|
||||
capman.resumecapture("fd")
|
||||
py.test.raises(ValueError, 'capman.resumecapture("fd")')
|
||||
py.test.raises(ValueError, 'capman.resumecapture("sys")')
|
||||
os.write(1, "hello\n".encode('ascii'))
|
||||
out, err = capman.suspendcapture()
|
||||
assert out == "hello\n"
|
||||
capman.resumecapture("sys")
|
||||
os.write(1, "hello\n".encode('ascii'))
|
||||
py.builtin.print_("world", file=sys.stderr)
|
||||
out, err = capman.suspendcapture()
|
||||
assert not out
|
||||
assert err == "world\n"
|
||||
finally:
|
||||
capouter.reset()
|
||||
|
||||
@py.test.mark.multi(method=['fd', 'sys'])
|
||||
def test_capturing_unicode(testdir, method):
|
||||
if sys.version_info >= (3,0):
|
||||
obj = "'b\u00f6y'"
|
||||
else:
|
||||
obj = "u'\u00f6y'"
|
||||
testdir.makepyfile("""
|
||||
# taken from issue 227 from nosetests
|
||||
def test_unicode():
|
||||
import sys
|
||||
print (sys.stdout)
|
||||
print (%s)
|
||||
""" % obj)
|
||||
result = testdir.runpytest("--capture=%s" % method)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*1 passed*"
|
||||
])
|
||||
|
||||
@py.test.mark.multi(method=['fd', 'sys'])
|
||||
def test_capturing_bytes_in_utf8_encoding(testdir, method):
|
||||
testdir.makepyfile("""
|
||||
def test_unicode():
|
||||
print ('b\\u00f6y')
|
||||
""")
|
||||
result = testdir.runpytest("--capture=%s" % method)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*1 passed*"
|
||||
])
|
||||
|
||||
def test_collect_capturing(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
print ("collect %s failure" % 13)
|
||||
import xyz42123
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*Captured stdout*",
|
||||
"*collect 13 failure*",
|
||||
])
|
||||
|
||||
class TestPerTestCapturing:
|
||||
def test_capture_and_fixtures(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def setup_module(mod):
|
||||
print ("setup module")
|
||||
def setup_function(function):
|
||||
print ("setup " + function.__name__)
|
||||
def test_func1():
|
||||
print ("in func1")
|
||||
assert 0
|
||||
def test_func2():
|
||||
print ("in func2")
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stdout.fnmatch_lines([
|
||||
"setup module*",
|
||||
"setup test_func1*",
|
||||
"in func1*",
|
||||
"setup test_func2*",
|
||||
"in func2*",
|
||||
])
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_capture_scope_cache(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import sys
|
||||
def setup_module(func):
|
||||
print ("module-setup")
|
||||
def setup_function(func):
|
||||
print ("function-setup")
|
||||
def test_func():
|
||||
print ("in function")
|
||||
assert 0
|
||||
def teardown_function(func):
|
||||
print ("in teardown")
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_func():*",
|
||||
"*Captured stdout during setup*",
|
||||
"module-setup*",
|
||||
"function-setup*",
|
||||
"*Captured stdout*",
|
||||
"in teardown*",
|
||||
])
|
||||
|
||||
|
||||
def test_no_carry_over(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_func1():
|
||||
print ("in func1")
|
||||
def test_func2():
|
||||
print ("in func2")
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
s = result.stdout.str()
|
||||
assert "in func1" not in s
|
||||
assert "in func2" in s
|
||||
|
||||
|
||||
def test_teardown_capturing(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def setup_function(function):
|
||||
print ("setup func1")
|
||||
def teardown_function(function):
|
||||
print ("teardown func1")
|
||||
assert 0
|
||||
def test_func1():
|
||||
print ("in func1")
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
'*teardown_function*',
|
||||
'*Captured stdout*',
|
||||
"setup func1*",
|
||||
"in func1*",
|
||||
"teardown func1*",
|
||||
#"*1 fixture failure*"
|
||||
])
|
||||
|
||||
def test_teardown_final_capturing(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def teardown_module(mod):
|
||||
print ("teardown module")
|
||||
assert 0
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*def teardown_module(mod):*",
|
||||
"*Captured stdout*",
|
||||
"*teardown module*",
|
||||
"*1 error*",
|
||||
])
|
||||
|
||||
def test_capturing_outerr(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
import sys
|
||||
def test_capturing():
|
||||
print (42)
|
||||
sys.stderr.write(str(23))
|
||||
def test_capturing_error():
|
||||
print (1)
|
||||
sys.stderr.write(str(2))
|
||||
raise ValueError
|
||||
""")
|
||||
result = testdir.runpytest(p1)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_capturing_outerr.py .F",
|
||||
"====* FAILURES *====",
|
||||
"____*____",
|
||||
"*test_capturing_outerr.py:8: ValueError",
|
||||
"*--- Captured stdout ---*",
|
||||
"1",
|
||||
"*--- Captured stderr ---*",
|
||||
"2",
|
||||
])
|
||||
|
||||
class TestLoggingInteraction:
|
||||
def test_logging_stream_ownership(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_logging():
|
||||
import logging
|
||||
import py
|
||||
stream = py.io.TextIO()
|
||||
logging.basicConfig(stream=stream)
|
||||
stream.close() # to free memory/release resources
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stderr.str().find("atexit") == -1
|
||||
|
||||
def test_capturing_and_logging_fundamentals(self, testdir):
|
||||
# here we check a fundamental feature
|
||||
rootdir = str(py.path.local(py.__file__).dirpath().dirpath())
|
||||
p = testdir.makepyfile("""
|
||||
import sys, os
|
||||
sys.path.insert(0, %r)
|
||||
import py, logging
|
||||
if hasattr(os, 'dup'):
|
||||
cap = py.io.StdCaptureFD(out=False, in_=False)
|
||||
else:
|
||||
cap = py.io.StdCapture(out=False, in_=False)
|
||||
logging.warn("hello1")
|
||||
outerr = cap.suspend()
|
||||
|
||||
print ("suspeneded and captured %%s" %% (outerr,))
|
||||
|
||||
logging.warn("hello2")
|
||||
|
||||
cap.resume()
|
||||
logging.warn("hello3")
|
||||
|
||||
outerr = cap.suspend()
|
||||
print ("suspend2 and captured %%s" %% (outerr,))
|
||||
""" % rootdir)
|
||||
result = testdir.runpython(p)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"suspeneded and captured*hello1*",
|
||||
"suspend2 and captured*hello2*WARNING:root:hello3*",
|
||||
])
|
||||
assert "atexit" not in result.stderr.str()
|
||||
|
||||
|
||||
def test_logging_and_immediate_setupteardown(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import logging
|
||||
def setup_function(function):
|
||||
logging.warn("hello1")
|
||||
|
||||
def test_logging():
|
||||
logging.warn("hello2")
|
||||
assert 0
|
||||
|
||||
def teardown_function(function):
|
||||
logging.warn("hello3")
|
||||
assert 0
|
||||
""")
|
||||
for optargs in (('--capture=sys',), ('--capture=fd',)):
|
||||
print (optargs)
|
||||
result = testdir.runpytest(p, *optargs)
|
||||
s = result.stdout.str()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*WARN*hello3", # errors show first!
|
||||
"*WARN*hello1",
|
||||
"*WARN*hello2",
|
||||
])
|
||||
# verify proper termination
|
||||
assert "closed" not in s
|
||||
|
||||
def test_logging_and_crossscope_fixtures(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import logging
|
||||
def setup_module(function):
|
||||
logging.warn("hello1")
|
||||
|
||||
def test_logging():
|
||||
logging.warn("hello2")
|
||||
assert 0
|
||||
|
||||
def teardown_module(function):
|
||||
logging.warn("hello3")
|
||||
assert 0
|
||||
""")
|
||||
for optargs in (('--capture=sys',), ('--capture=fd',)):
|
||||
print (optargs)
|
||||
result = testdir.runpytest(p, *optargs)
|
||||
s = result.stdout.str()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*WARN*hello3", # errors come first
|
||||
"*WARN*hello1",
|
||||
"*WARN*hello2",
|
||||
])
|
||||
# verify proper termination
|
||||
assert "closed" not in s
|
||||
|
||||
class TestCaptureFuncarg:
|
||||
def test_std_functional(self, testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
def test_hello(capsys):
|
||||
print (42)
|
||||
out, err = capsys.readouterr()
|
||||
assert out.startswith("42")
|
||||
""")
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
@needsosdup
|
||||
def test_stdfd_functional(self, testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
def test_hello(capfd):
|
||||
import os
|
||||
os.write(1, "42".encode('ascii'))
|
||||
out, err = capfd.readouterr()
|
||||
assert out.startswith("42")
|
||||
capfd.close()
|
||||
""")
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_partial_setup_failure(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_hello(capfd, missingarg):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*test_partial_setup_failure*",
|
||||
"*1 error*",
|
||||
])
|
||||
|
||||
@needsosdup
|
||||
def test_keyboardinterrupt_disables_capturing(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_hello(capfd):
|
||||
import os
|
||||
os.write(1, str(42).encode('ascii'))
|
||||
raise KeyboardInterrupt()
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*KEYBOARD INTERRUPT*"
|
||||
])
|
||||
assert result.ret == 2
|
||||
|
||||
85
testing/plugin/test_pytest_default.py
Normal file
85
testing/plugin/test_pytest_default.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import py
|
||||
from py.plugin.pytest_default import pytest_report_iteminfo
|
||||
|
||||
def test_implied_different_sessions(tmpdir):
|
||||
def x(*args):
|
||||
config = py.test.config._reparse([tmpdir] + list(args))
|
||||
try:
|
||||
config.pluginmanager.do_configure(config)
|
||||
except ValueError:
|
||||
return Exception
|
||||
return getattr(config._sessionclass, '__name__', None)
|
||||
assert x() == None
|
||||
py.test.importorskip("execnet")
|
||||
assert x('-d') == 'DSession'
|
||||
assert x('--dist=each') == 'DSession'
|
||||
assert x('-n3') == 'DSession'
|
||||
assert x('-f') == 'LooponfailingSession'
|
||||
|
||||
def test_plugin_specify(testdir):
|
||||
testdir.chdir()
|
||||
config = py.test.raises(ImportError, """
|
||||
testdir.parseconfig("-p", "nqweotexistent")
|
||||
""")
|
||||
#py.test.raises(ImportError,
|
||||
# "config.pluginmanager.do_configure(config)"
|
||||
#)
|
||||
|
||||
def test_plugin_already_exists(testdir):
|
||||
config = testdir.parseconfig("-p", "default")
|
||||
assert config.option.plugins == ['default']
|
||||
config.pluginmanager.do_configure(config)
|
||||
|
||||
|
||||
class TestDistOptions:
|
||||
def setup_method(self, method):
|
||||
py.test.importorskip("execnet")
|
||||
def test_getxspecs(self, testdir):
|
||||
config = testdir.parseconfigure("--tx=popen", "--tx", "ssh=xyz")
|
||||
xspecs = config.getxspecs()
|
||||
assert len(xspecs) == 2
|
||||
print(xspecs)
|
||||
assert xspecs[0].popen
|
||||
assert xspecs[1].ssh == "xyz"
|
||||
|
||||
def test_xspecs_multiplied(self, testdir):
|
||||
xspecs = testdir.parseconfigure("--tx=3*popen",).getxspecs()
|
||||
assert len(xspecs) == 3
|
||||
assert xspecs[1].popen
|
||||
|
||||
def test_getrsyncdirs(self, testdir):
|
||||
config = testdir.parseconfigure('--rsyncdir=' + str(testdir.tmpdir))
|
||||
roots = config.getrsyncdirs()
|
||||
assert len(roots) == 1 + len(py._pydirs)
|
||||
assert testdir.tmpdir in roots
|
||||
|
||||
def test_getrsyncdirs_with_conftest(self, testdir):
|
||||
p = py.path.local()
|
||||
for bn in 'x y z'.split():
|
||||
p.mkdir(bn)
|
||||
testdir.makeconftest("""
|
||||
rsyncdirs= 'x',
|
||||
""")
|
||||
config = testdir.parseconfigure(testdir.tmpdir, '--rsyncdir=y', '--rsyncdir=z')
|
||||
roots = config.getrsyncdirs()
|
||||
assert len(roots) == 3 + len(py._pydirs)
|
||||
assert py.path.local('y') in roots
|
||||
assert py.path.local('z') in roots
|
||||
assert testdir.tmpdir.join('x') in roots
|
||||
|
||||
def test_dist_options(self, testdir):
|
||||
config = testdir.parseconfigure("-n 2")
|
||||
assert config.option.dist == "load"
|
||||
assert config.option.tx == ['popen'] * 2
|
||||
|
||||
config = testdir.parseconfigure("-d")
|
||||
assert config.option.dist == "load"
|
||||
|
||||
def test_pytest_report_iteminfo():
|
||||
class FakeItem(object):
|
||||
|
||||
def reportinfo(self):
|
||||
return "-reportinfo-"
|
||||
|
||||
res = pytest_report_iteminfo(FakeItem())
|
||||
assert res == "-reportinfo-"
|
||||
103
testing/plugin/test_pytest_doctest.py
Normal file
103
testing/plugin/test_pytest_doctest.py
Normal file
@@ -0,0 +1,103 @@
|
||||
from py.plugin.pytest_doctest import DoctestModule, DoctestTextfile
|
||||
|
||||
class TestDoctests:
|
||||
|
||||
def test_collect_testtextfile(self, testdir):
|
||||
testdir.maketxtfile(whatever="")
|
||||
checkfile = testdir.maketxtfile(test_something="""
|
||||
alskdjalsdk
|
||||
>>> i = 5
|
||||
>>> i-1
|
||||
4
|
||||
""")
|
||||
for x in (testdir.tmpdir, checkfile):
|
||||
#print "checking that %s returns custom items" % (x,)
|
||||
items, reprec = testdir.inline_genitems(x)
|
||||
assert len(items) == 1
|
||||
assert isinstance(items[0], DoctestTextfile)
|
||||
|
||||
def test_collect_module(self, testdir):
|
||||
path = testdir.makepyfile(whatever="#")
|
||||
for p in (path, testdir.tmpdir):
|
||||
items, reprec = testdir.inline_genitems(p, '--doctest-modules')
|
||||
assert len(items) == 1
|
||||
assert isinstance(items[0], DoctestModule)
|
||||
|
||||
def test_simple_doctestfile(self, testdir):
|
||||
p = testdir.maketxtfile(test_doc="""
|
||||
>>> x = 1
|
||||
>>> x == 1
|
||||
False
|
||||
""")
|
||||
reprec = testdir.inline_run(p)
|
||||
reprec.assertoutcome(failed=1)
|
||||
|
||||
def test_doctest_unexpected_exception(self, testdir):
|
||||
from py.impl.test.outcome import Failed
|
||||
|
||||
p = testdir.maketxtfile("""
|
||||
>>> i = 0
|
||||
>>> i = 1
|
||||
>>> x
|
||||
2
|
||||
""")
|
||||
reprec = testdir.inline_run(p)
|
||||
call = reprec.getcall("pytest_runtest_logreport")
|
||||
assert call.report.failed
|
||||
assert call.report.longrepr
|
||||
# XXX
|
||||
#testitem, = items
|
||||
#excinfo = py.test.raises(Failed, "testitem.runtest()")
|
||||
#repr = testitem.repr_failure(excinfo, ("", ""))
|
||||
#assert repr.reprlocation
|
||||
|
||||
def test_doctestmodule(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
'''
|
||||
>>> x = 1
|
||||
>>> x == 1
|
||||
False
|
||||
|
||||
'''
|
||||
""")
|
||||
reprec = testdir.inline_run(p, "--doctest-modules")
|
||||
reprec.assertoutcome(failed=1)
|
||||
|
||||
def test_doctestmodule_external(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
#
|
||||
def somefunc():
|
||||
'''
|
||||
>>> i = 0
|
||||
>>> i + 1
|
||||
2
|
||||
'''
|
||||
""")
|
||||
result = testdir.runpytest(p, "--doctest-modules")
|
||||
result.stdout.fnmatch_lines([
|
||||
'004 *>>> i = 0',
|
||||
'005 *>>> i + 1',
|
||||
'*Expected:',
|
||||
"* 2",
|
||||
"*Got:",
|
||||
"* 1",
|
||||
"*:5: DocTestFailure"
|
||||
])
|
||||
|
||||
|
||||
def test_txtfile_failing(self, testdir):
|
||||
p = testdir.maketxtfile("""
|
||||
>>> i = 0
|
||||
>>> i + 1
|
||||
2
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
result.stdout.fnmatch_lines([
|
||||
'001 >>> i = 0',
|
||||
'002 >>> i + 1',
|
||||
'Expected:',
|
||||
" 2",
|
||||
"Got:",
|
||||
" 1",
|
||||
"*test_txtfile_failing.txt:2: DocTestFailure"
|
||||
])
|
||||
17
testing/plugin/test_pytest_figleaf.py
Normal file
17
testing/plugin/test_pytest_figleaf.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import py
|
||||
|
||||
def test_functional(testdir):
|
||||
py.test.importorskip("figleaf")
|
||||
testdir.plugins.append("figleaf")
|
||||
testdir.makepyfile("""
|
||||
def f():
|
||||
x = 42
|
||||
def test_whatever():
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest('-F')
|
||||
assert result.ret == 0
|
||||
assert result.stdout.fnmatch_lines([
|
||||
'*figleaf html*'
|
||||
])
|
||||
#print result.stdout.str()
|
||||
18
testing/plugin/test_pytest_helpconfig.py
Normal file
18
testing/plugin/test_pytest_helpconfig.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import py, os
|
||||
|
||||
def test_version(testdir):
|
||||
assert py.version == py.__version__
|
||||
result = testdir.runpytest("--version")
|
||||
assert result.ret == 0
|
||||
p = py.path.local(py.__file__).dirpath()
|
||||
assert result.stderr.fnmatch_lines([
|
||||
'*py.test*%s*imported from*%s*' % (py.version, p)
|
||||
])
|
||||
|
||||
def test_helpconfig(testdir):
|
||||
result = testdir.runpytest("--help-config")
|
||||
assert result.ret == 0
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*cmdline*conftest*ENV*",
|
||||
])
|
||||
|
||||
12
testing/plugin/test_pytest_hooklog.py
Normal file
12
testing/plugin/test_pytest_hooklog.py
Normal file
@@ -0,0 +1,12 @@
|
||||
import py
|
||||
|
||||
def test_functional(testdir):
|
||||
testdir.makepyfile("""
|
||||
def test_pass():
|
||||
pass
|
||||
""")
|
||||
testdir.runpytest("--hooklog=hook.log")
|
||||
s = testdir.tmpdir.join("hook.log").read()
|
||||
assert s.find("pytest_sessionstart") != -1
|
||||
assert s.find("ItemTestReport") != -1
|
||||
assert s.find("sessionfinish") != -1
|
||||
110
testing/plugin/test_pytest_mark.py
Normal file
110
testing/plugin/test_pytest_mark.py
Normal file
@@ -0,0 +1,110 @@
|
||||
import py
|
||||
from py.plugin.pytest_mark import Mark
|
||||
|
||||
class TestMark:
|
||||
def test_pytest_mark_notcallable(self):
|
||||
mark = Mark()
|
||||
py.test.raises(TypeError, "mark()")
|
||||
|
||||
def test_pytest_mark_bare(self):
|
||||
mark = Mark()
|
||||
def f(): pass
|
||||
mark.hello(f)
|
||||
assert f.hello
|
||||
|
||||
def test_pytest_mark_keywords(self):
|
||||
mark = Mark()
|
||||
def f(): pass
|
||||
mark.world(x=3, y=4)(f)
|
||||
assert f.world
|
||||
assert f.world.x == 3
|
||||
assert f.world.y == 4
|
||||
|
||||
def test_apply_multiple_and_merge(self):
|
||||
mark = Mark()
|
||||
def f(): pass
|
||||
marker = mark.world
|
||||
mark.world(x=3)(f)
|
||||
assert f.world.x == 3
|
||||
mark.world(y=4)(f)
|
||||
assert f.world.x == 3
|
||||
assert f.world.y == 4
|
||||
mark.world(y=1)(f)
|
||||
assert f.world.y == 1
|
||||
assert len(f.world.args) == 0
|
||||
|
||||
def test_pytest_mark_positional(self):
|
||||
mark = Mark()
|
||||
def f(): pass
|
||||
mark.world("hello")(f)
|
||||
assert f.world.args[0] == "hello"
|
||||
mark.world("world")(f)
|
||||
|
||||
def test_oldstyle_marker_access(self, recwarn):
|
||||
mark = Mark()
|
||||
def f(): pass
|
||||
mark.world(x=1)(f)
|
||||
assert f.world.x == 1
|
||||
assert recwarn.pop()
|
||||
|
||||
class TestFunctional:
|
||||
def test_mark_per_function(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
@py.test.mark.hello
|
||||
def test_hello():
|
||||
assert hasattr(test_hello, 'hello')
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
assert result.stdout.fnmatch_lines(["*passed*"])
|
||||
|
||||
def test_mark_per_module(self, testdir):
|
||||
item = testdir.getitem("""
|
||||
import py
|
||||
pytestmark = py.test.mark.hello
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
keywords = item.readkeywords()
|
||||
assert 'hello' in keywords
|
||||
|
||||
def test_mark_per_class(self, testdir):
|
||||
modcol = testdir.getmodulecol("""
|
||||
import py
|
||||
class TestClass:
|
||||
pytestmark = py.test.mark.hello
|
||||
def test_func(self):
|
||||
assert TestClass.test_func.hello
|
||||
""")
|
||||
clscol = modcol.collect()[0]
|
||||
item = clscol.collect()[0].collect()[0]
|
||||
keywords = item.readkeywords()
|
||||
assert 'hello' in keywords
|
||||
|
||||
def test_merging_markers(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
pytestmark = py.test.mark.hello("pos1", x=1, y=2)
|
||||
class TestClass:
|
||||
# classlevel overrides module level
|
||||
pytestmark = py.test.mark.hello(x=3)
|
||||
@py.test.mark.hello("pos0", z=4)
|
||||
def test_func(self):
|
||||
pass
|
||||
""")
|
||||
items, rec = testdir.inline_genitems(p)
|
||||
item, = items
|
||||
keywords = item.readkeywords()
|
||||
marker = keywords['hello']
|
||||
assert marker.args == ["pos0", "pos1"]
|
||||
assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4}
|
||||
|
||||
def test_mark_other(self, testdir):
|
||||
item = testdir.getitem("""
|
||||
import py
|
||||
class pytestmark:
|
||||
pass
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
keywords = item.readkeywords()
|
||||
140
testing/plugin/test_pytest_monkeypatch.py
Normal file
140
testing/plugin/test_pytest_monkeypatch.py
Normal file
@@ -0,0 +1,140 @@
|
||||
import os, sys
|
||||
import py
|
||||
from py.plugin.pytest_monkeypatch import MonkeyPatch
|
||||
|
||||
def test_setattr():
|
||||
class A:
|
||||
x = 1
|
||||
monkeypatch = MonkeyPatch()
|
||||
py.test.raises(AttributeError, "monkeypatch.setattr(A, 'notexists', 2)")
|
||||
monkeypatch.setattr(A, 'y', 2, raising=False)
|
||||
assert A.y == 2
|
||||
monkeypatch.undo()
|
||||
assert not hasattr(A, 'y')
|
||||
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.setattr(A, 'x', 2)
|
||||
assert A.x == 2
|
||||
monkeypatch.setattr(A, 'x', 3)
|
||||
assert A.x == 3
|
||||
monkeypatch.undo()
|
||||
assert A.x == 1
|
||||
|
||||
A.x = 5
|
||||
monkeypatch.undo() # double-undo makes no modification
|
||||
assert A.x == 5
|
||||
|
||||
def test_delattr():
|
||||
class A:
|
||||
x = 1
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.delattr(A, 'x')
|
||||
assert not hasattr(A, 'x')
|
||||
monkeypatch.undo()
|
||||
assert A.x == 1
|
||||
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.delattr(A, 'x')
|
||||
py.test.raises(AttributeError, "monkeypatch.delattr(A, 'y')")
|
||||
monkeypatch.delattr(A, 'y', raising=False)
|
||||
monkeypatch.setattr(A, 'x', 5, raising=False)
|
||||
assert A.x == 5
|
||||
monkeypatch.undo()
|
||||
assert A.x == 1
|
||||
|
||||
def test_setitem():
|
||||
d = {'x': 1}
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.setitem(d, 'x', 2)
|
||||
monkeypatch.setitem(d, 'y', 1700)
|
||||
monkeypatch.setitem(d, 'y', 1700)
|
||||
assert d['x'] == 2
|
||||
assert d['y'] == 1700
|
||||
monkeypatch.setitem(d, 'x', 3)
|
||||
assert d['x'] == 3
|
||||
monkeypatch.undo()
|
||||
assert d['x'] == 1
|
||||
assert 'y' not in d
|
||||
d['x'] = 5
|
||||
monkeypatch.undo()
|
||||
assert d['x'] == 5
|
||||
|
||||
def test_delitem():
|
||||
d = {'x': 1}
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.delitem(d, 'x')
|
||||
assert 'x' not in d
|
||||
monkeypatch.delitem(d, 'y', raising=False)
|
||||
py.test.raises(KeyError, "monkeypatch.delitem(d, 'y')")
|
||||
assert not d
|
||||
monkeypatch.setitem(d, 'y', 1700)
|
||||
assert d['y'] == 1700
|
||||
d['hello'] = 'world'
|
||||
monkeypatch.setitem(d, 'x', 1500)
|
||||
assert d['x'] == 1500
|
||||
monkeypatch.undo()
|
||||
assert d == {'hello': 'world', 'x': 1}
|
||||
|
||||
def test_setenv():
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.setenv('XYZ123', 2)
|
||||
import os
|
||||
assert os.environ['XYZ123'] == "2"
|
||||
monkeypatch.undo()
|
||||
assert 'XYZ123' not in os.environ
|
||||
|
||||
def test_delenv():
|
||||
name = 'xyz1234'
|
||||
assert name not in os.environ
|
||||
monkeypatch = MonkeyPatch()
|
||||
py.test.raises(KeyError, "monkeypatch.delenv(%r, raising=True)" % name)
|
||||
monkeypatch.delenv(name, raising=False)
|
||||
monkeypatch.undo()
|
||||
os.environ[name] = "1"
|
||||
try:
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.delenv(name)
|
||||
assert name not in os.environ
|
||||
monkeypatch.setenv(name, "3")
|
||||
assert os.environ[name] == "3"
|
||||
monkeypatch.undo()
|
||||
assert os.environ[name] == "1"
|
||||
finally:
|
||||
if name in os.environ:
|
||||
del os.environ[name]
|
||||
|
||||
def test_setenv_prepend():
|
||||
import os
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.setenv('XYZ123', 2, prepend="-")
|
||||
assert os.environ['XYZ123'] == "2"
|
||||
monkeypatch.setenv('XYZ123', 3, prepend="-")
|
||||
assert os.environ['XYZ123'] == "3-2"
|
||||
monkeypatch.undo()
|
||||
assert 'XYZ123' not in os.environ
|
||||
|
||||
def test_monkeypatch_plugin(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
pytest_plugins = 'pytest_monkeypatch',
|
||||
def test_method(monkeypatch):
|
||||
assert monkeypatch.__class__.__name__ == "MonkeyPatch"
|
||||
""")
|
||||
res = reprec.countoutcomes()
|
||||
assert tuple(res) == (1, 0, 0), res
|
||||
|
||||
def test_syspath_prepend():
|
||||
old = list(sys.path)
|
||||
try:
|
||||
monkeypatch = MonkeyPatch()
|
||||
monkeypatch.syspath_prepend('world')
|
||||
monkeypatch.syspath_prepend('hello')
|
||||
assert sys.path[0] == "hello"
|
||||
assert sys.path[1] == "world"
|
||||
monkeypatch.undo()
|
||||
assert sys.path == old
|
||||
monkeypatch.undo()
|
||||
assert sys.path == old
|
||||
finally:
|
||||
sys.path[:] = old
|
||||
|
||||
|
||||
138
testing/plugin/test_pytest_nose.py
Normal file
138
testing/plugin/test_pytest_nose.py
Normal file
@@ -0,0 +1,138 @@
|
||||
import py
|
||||
py.test.importorskip("nose")
|
||||
|
||||
def test_nose_setup(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
l = []
|
||||
|
||||
def test_hello():
|
||||
assert l == [1]
|
||||
def test_world():
|
||||
assert l == [1,2]
|
||||
test_hello.setup = lambda: l.append(1)
|
||||
test_hello.teardown = lambda: l.append(2)
|
||||
""")
|
||||
result = testdir.runpytest(p, '-p', 'nose')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*2 passed*"
|
||||
])
|
||||
|
||||
def test_nose_test_generator_fixtures(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
# taken from nose-0.11.1 unit_tests/test_generator_fixtures.py
|
||||
from nose.tools import eq_
|
||||
called = []
|
||||
|
||||
def outer_setup():
|
||||
called.append('outer_setup')
|
||||
|
||||
def outer_teardown():
|
||||
called.append('outer_teardown')
|
||||
|
||||
def inner_setup():
|
||||
called.append('inner_setup')
|
||||
|
||||
def inner_teardown():
|
||||
called.append('inner_teardown')
|
||||
|
||||
def test_gen():
|
||||
called[:] = []
|
||||
for i in range(0, 5):
|
||||
yield check, i
|
||||
|
||||
def check(i):
|
||||
expect = ['outer_setup']
|
||||
for x in range(0, i):
|
||||
expect.append('inner_setup')
|
||||
expect.append('inner_teardown')
|
||||
expect.append('inner_setup')
|
||||
eq_(called, expect)
|
||||
|
||||
|
||||
test_gen.setup = outer_setup
|
||||
test_gen.teardown = outer_teardown
|
||||
check.setup = inner_setup
|
||||
check.teardown = inner_teardown
|
||||
|
||||
class TestClass(object):
|
||||
def setup(self):
|
||||
print "setup called in", self
|
||||
self.called = ['setup']
|
||||
|
||||
def teardown(self):
|
||||
print "teardown called in", self
|
||||
eq_(self.called, ['setup'])
|
||||
self.called.append('teardown')
|
||||
|
||||
def test(self):
|
||||
print "test called in", self
|
||||
for i in range(0, 5):
|
||||
yield self.check, i
|
||||
|
||||
def check(self, i):
|
||||
print "check called in", self
|
||||
expect = ['setup']
|
||||
#for x in range(0, i):
|
||||
# expect.append('setup')
|
||||
# expect.append('teardown')
|
||||
#expect.append('setup')
|
||||
eq_(self.called, expect)
|
||||
|
||||
""")
|
||||
result = testdir.runpytest(p, '-p', 'nose')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*10 passed*"
|
||||
])
|
||||
|
||||
|
||||
|
||||
def test_module_level_setup(testdir):
|
||||
testdir.makepyfile("""
|
||||
from nose.tools import with_setup
|
||||
items = {}
|
||||
def setup():
|
||||
items[1]=1
|
||||
|
||||
def teardown():
|
||||
del items[1]
|
||||
|
||||
def setup2():
|
||||
items[2] = 2
|
||||
|
||||
def teardown2():
|
||||
del items[2]
|
||||
|
||||
def test_setup_module_setup():
|
||||
assert items[1] == 1
|
||||
|
||||
@with_setup(setup2, teardown2)
|
||||
def test_local_setup():
|
||||
assert items[2] == 2
|
||||
assert 1 not in items
|
||||
|
||||
""")
|
||||
result = testdir.runpytest('-p', 'nose')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*2 passed*",
|
||||
])
|
||||
|
||||
def test_nose_style_setup_teardown(testdir):
|
||||
testdir.makepyfile("""
|
||||
l = []
|
||||
def setup_module():
|
||||
l.append(1)
|
||||
|
||||
def teardown_module():
|
||||
del l[0]
|
||||
|
||||
def test_hello():
|
||||
assert l == [1]
|
||||
|
||||
def test_world():
|
||||
assert l == [1]
|
||||
""")
|
||||
result = testdir.runpytest('-p', 'nose')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*2 passed*",
|
||||
])
|
||||
|
||||
47
testing/plugin/test_pytest_pastebin.py
Normal file
47
testing/plugin/test_pytest_pastebin.py
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
class TestPasting:
|
||||
def pytest_funcarg__pastebinlist(self, request):
|
||||
mp = request.getfuncargvalue("monkeypatch")
|
||||
pastebinlist = []
|
||||
class MockProxy:
|
||||
def newPaste(self, language, code):
|
||||
pastebinlist.append((language, code))
|
||||
plugin = request.config.pluginmanager.getplugin('pastebin')
|
||||
mp.setattr(plugin, 'getproxy', MockProxy)
|
||||
return pastebinlist
|
||||
|
||||
def test_failed(self, testdir, pastebinlist):
|
||||
testpath = testdir.makepyfile("""
|
||||
import py
|
||||
def test_pass():
|
||||
pass
|
||||
def test_fail():
|
||||
assert 0
|
||||
def test_skip():
|
||||
py.test.skip("")
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath, "--paste=failed")
|
||||
assert len(pastebinlist) == 1
|
||||
assert pastebinlist[0][0] == "python"
|
||||
s = pastebinlist[0][1]
|
||||
assert s.find("def test_fail") != -1
|
||||
assert reprec.countoutcomes() == [1,1,1]
|
||||
|
||||
def test_all(self, testdir, pastebinlist):
|
||||
testpath = testdir.makepyfile("""
|
||||
import py
|
||||
def test_pass():
|
||||
pass
|
||||
def test_fail():
|
||||
assert 0
|
||||
def test_skip():
|
||||
py.test.skip("")
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath, "--pastebin=all")
|
||||
assert reprec.countoutcomes() == [1,1,1]
|
||||
assert len(pastebinlist) == 1
|
||||
assert pastebinlist[0][0] == "python"
|
||||
s = pastebinlist[0][1]
|
||||
for x in 'test_fail test_skip skipped'.split():
|
||||
assert s.find(x), (s, x)
|
||||
|
||||
56
testing/plugin/test_pytest_pdb.py
Normal file
56
testing/plugin/test_pytest_pdb.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import py
|
||||
|
||||
class TestPDB:
|
||||
def pytest_funcarg__pdblist(self, request):
|
||||
monkeypatch = request.getfuncargvalue("monkeypatch")
|
||||
pdblist = []
|
||||
def mypdb(*args):
|
||||
pdblist.append(args)
|
||||
plugin = request.config.pluginmanager.getplugin('pdb')
|
||||
monkeypatch.setattr(plugin, 'post_mortem', mypdb)
|
||||
return pdblist
|
||||
|
||||
def test_pdb_on_fail(self, testdir, pdblist):
|
||||
rep = testdir.inline_runsource1('--pdb', """
|
||||
def test_func():
|
||||
assert 0
|
||||
""")
|
||||
assert rep.failed
|
||||
assert len(pdblist) == 1
|
||||
tb = py.code.Traceback(pdblist[0][0])
|
||||
assert tb[-1].name == "test_func"
|
||||
|
||||
def test_pdb_on_skip(self, testdir, pdblist):
|
||||
rep = testdir.inline_runsource1('--pdb', """
|
||||
import py
|
||||
def test_func():
|
||||
py.test.skip("hello")
|
||||
""")
|
||||
assert rep.skipped
|
||||
assert len(pdblist) == 0
|
||||
|
||||
def test_pdb_interaction(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
def test_1():
|
||||
i = 0
|
||||
assert i == 1
|
||||
""")
|
||||
child = testdir.spawn_pytest("--pdb %s" % p1)
|
||||
#child.expect(".*def test_1.*")
|
||||
child.expect(".*i = 0.*")
|
||||
child.expect("(Pdb)")
|
||||
child.sendeof()
|
||||
child.expect("1 failed")
|
||||
if child.isalive():
|
||||
child.wait()
|
||||
|
||||
def test_dist_incompatibility_messages(self, testdir):
|
||||
py.test.importorskip("execnet")
|
||||
Error = py.test.config.Error
|
||||
py.test.raises(Error, "testdir.parseconfigure('--pdb', '--looponfail')")
|
||||
result = testdir.runpytest("--pdb", "-n", "3")
|
||||
assert result.ret != 0
|
||||
assert "incompatible" in result.stdout.str()
|
||||
result = testdir.runpytest("--pdb", "-d", "--tx", "popen")
|
||||
assert result.ret != 0
|
||||
assert "incompatible" in result.stdout.str()
|
||||
70
testing/plugin/test_pytest_pytester.py
Normal file
70
testing/plugin/test_pytest_pytester.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import py
|
||||
from py.plugin.pytest_pytester import LineMatcher, LineComp
|
||||
|
||||
def test_reportrecorder(testdir):
|
||||
registry = py._com.Registry()
|
||||
recorder = testdir.getreportrecorder(registry)
|
||||
assert not recorder.getfailures()
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
class rep:
|
||||
excinfo = None
|
||||
passed = False
|
||||
failed = True
|
||||
skipped = False
|
||||
when = "call"
|
||||
|
||||
recorder.hook.pytest_runtest_logreport(report=rep)
|
||||
failures = recorder.getfailures()
|
||||
assert failures == [rep]
|
||||
failures = recorder.getfailures()
|
||||
assert failures == [rep]
|
||||
|
||||
class rep:
|
||||
excinfo = None
|
||||
passed = False
|
||||
failed = False
|
||||
skipped = True
|
||||
when = "call"
|
||||
rep.passed = False
|
||||
rep.skipped = True
|
||||
recorder.hook.pytest_runtest_logreport(report=rep)
|
||||
|
||||
modcol = testdir.getmodulecol("")
|
||||
rep = modcol.config.hook.pytest_make_collect_report(collector=modcol)
|
||||
rep.passed = False
|
||||
rep.failed = True
|
||||
rep.skipped = False
|
||||
recorder.hook.pytest_collectreport(report=rep)
|
||||
|
||||
passed, skipped, failed = recorder.listoutcomes()
|
||||
assert not passed and skipped and failed
|
||||
|
||||
numpassed, numskipped, numfailed = recorder.countoutcomes()
|
||||
assert numpassed == 0
|
||||
assert numskipped == 1
|
||||
assert numfailed == 1
|
||||
assert len(recorder.getfailedcollections()) == 1
|
||||
|
||||
recorder.unregister()
|
||||
recorder.clear()
|
||||
recorder.hook.pytest_runtest_logreport(report=rep)
|
||||
py.test.raises(ValueError, "recorder.getfailures()")
|
||||
|
||||
|
||||
def test_parseconfig(testdir):
|
||||
config1 = testdir.parseconfig()
|
||||
config2 = testdir.parseconfig()
|
||||
assert config2 != config1
|
||||
assert config1 != py.test.config
|
||||
|
||||
def test_testdir_runs_with_plugin(testdir):
|
||||
testdir.makepyfile("""
|
||||
pytest_plugins = "pytest_pytester"
|
||||
def test_hello(testdir):
|
||||
assert 1
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*1 passed*"
|
||||
])
|
||||
|
||||
81
testing/plugin/test_pytest_recwarn.py
Normal file
81
testing/plugin/test_pytest_recwarn.py
Normal file
@@ -0,0 +1,81 @@
|
||||
import py
|
||||
from py.plugin.pytest_recwarn import WarningsRecorder
|
||||
|
||||
def test_WarningRecorder():
|
||||
showwarning = py.std.warnings.showwarning
|
||||
rec = WarningsRecorder()
|
||||
assert py.std.warnings.showwarning != showwarning
|
||||
assert not rec.list
|
||||
py.std.warnings.warn_explicit("hello", UserWarning, "xyz", 13)
|
||||
assert len(rec.list) == 1
|
||||
py.std.warnings.warn(DeprecationWarning("hello"))
|
||||
assert len(rec.list) == 2
|
||||
warn = rec.pop()
|
||||
assert str(warn.message) == "hello"
|
||||
l = rec.list
|
||||
rec.clear()
|
||||
assert len(rec.list) == 0
|
||||
assert l is rec.list
|
||||
py.test.raises(AssertionError, "rec.pop()")
|
||||
rec.finalize()
|
||||
assert showwarning == py.std.warnings.showwarning
|
||||
|
||||
def test_recwarn_functional(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
pytest_plugins = 'pytest_recwarn',
|
||||
import warnings
|
||||
oldwarn = warnings.showwarning
|
||||
def test_method(recwarn):
|
||||
assert warnings.showwarning != oldwarn
|
||||
warnings.warn("hello")
|
||||
warn = recwarn.pop()
|
||||
assert isinstance(warn.message, UserWarning)
|
||||
def test_finalized():
|
||||
assert warnings.showwarning == oldwarn
|
||||
""")
|
||||
res = reprec.countoutcomes()
|
||||
assert tuple(res) == (2, 0, 0), res
|
||||
|
||||
#
|
||||
# ============ test py.test.deprecated_call() ==============
|
||||
#
|
||||
|
||||
def dep(i):
|
||||
if i == 0:
|
||||
py.std.warnings.warn("is deprecated", DeprecationWarning)
|
||||
return 42
|
||||
|
||||
reg = {}
|
||||
def dep_explicit(i):
|
||||
if i == 0:
|
||||
py.std.warnings.warn_explicit("dep_explicit", category=DeprecationWarning,
|
||||
filename="hello", lineno=3)
|
||||
|
||||
def test_deprecated_call_raises():
|
||||
excinfo = py.test.raises(AssertionError,
|
||||
"py.test.deprecated_call(dep, 3)")
|
||||
assert str(excinfo).find("did not produce") != -1
|
||||
|
||||
def test_deprecated_call():
|
||||
py.test.deprecated_call(dep, 0)
|
||||
|
||||
def test_deprecated_call_ret():
|
||||
ret = py.test.deprecated_call(dep, 0)
|
||||
assert ret == 42
|
||||
|
||||
def test_deprecated_call_preserves():
|
||||
r = py.std.warnings.onceregistry.copy()
|
||||
f = py.std.warnings.filters[:]
|
||||
test_deprecated_call_raises()
|
||||
test_deprecated_call()
|
||||
assert r == py.std.warnings.onceregistry
|
||||
assert f == py.std.warnings.filters
|
||||
|
||||
def test_deprecated_explicit_call_raises():
|
||||
py.test.raises(AssertionError,
|
||||
"py.test.deprecated_call(dep_explicit, 3)")
|
||||
|
||||
def test_deprecated_explicit_call():
|
||||
py.test.deprecated_call(dep_explicit, 0)
|
||||
py.test.deprecated_call(dep_explicit, 0)
|
||||
|
||||
138
testing/plugin/test_pytest_restdoc.py
Normal file
138
testing/plugin/test_pytest_restdoc.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from py.plugin.pytest_restdoc import deindent
|
||||
|
||||
def test_deindent():
|
||||
assert deindent('foo') == 'foo'
|
||||
assert deindent('foo\n bar') == 'foo\n bar'
|
||||
assert deindent(' foo\n bar\n') == 'foo\nbar\n'
|
||||
assert deindent(' foo\n\n bar\n') == 'foo\n\nbar\n'
|
||||
assert deindent(' foo\n bar\n') == 'foo\n bar\n'
|
||||
assert deindent(' foo\n bar\n') == ' foo\nbar\n'
|
||||
|
||||
class TestApigenLinkRole:
|
||||
disabled = True
|
||||
|
||||
# these tests are moved here from the former py/doc/conftest.py
|
||||
def test_resolve_linkrole(self):
|
||||
from py.impl.doc.conftest import get_apigen_relpath
|
||||
apigen_relpath = get_apigen_relpath()
|
||||
|
||||
assert resolve_linkrole('api', 'py.foo.bar', False) == (
|
||||
'py.foo.bar', apigen_relpath + 'api/foo.bar.html')
|
||||
assert resolve_linkrole('api', 'py.foo.bar()', False) == (
|
||||
'py.foo.bar()', apigen_relpath + 'api/foo.bar.html')
|
||||
assert resolve_linkrole('api', 'py', False) == (
|
||||
'py', apigen_relpath + 'api/index.html')
|
||||
py.test.raises(AssertionError, 'resolve_linkrole("api", "foo.bar")')
|
||||
assert resolve_linkrole('source', 'py/foo/bar.py', False) == (
|
||||
'py/foo/bar.py', apigen_relpath + 'source/foo/bar.py.html')
|
||||
assert resolve_linkrole('source', 'py/foo/', False) == (
|
||||
'py/foo/', apigen_relpath + 'source/foo/index.html')
|
||||
assert resolve_linkrole('source', 'py/', False) == (
|
||||
'py/', apigen_relpath + 'source/index.html')
|
||||
py.test.raises(AssertionError, 'resolve_linkrole("source", "/foo/bar/")')
|
||||
|
||||
def test_resolve_linkrole_check_api(self):
|
||||
assert resolve_linkrole('api', 'py.test.ensuretemp')
|
||||
py.test.raises(AssertionError, "resolve_linkrole('api', 'py.foo.baz')")
|
||||
|
||||
def test_resolve_linkrole_check_source(self):
|
||||
assert resolve_linkrole('source', 'py/path/common.py')
|
||||
py.test.raises(AssertionError,
|
||||
"resolve_linkrole('source', 'py/foo/bar.py')")
|
||||
|
||||
|
||||
class TestDoctest:
|
||||
def pytest_funcarg__testdir(self, request):
|
||||
testdir = request.getfuncargvalue("testdir")
|
||||
assert request.module.__name__ == __name__
|
||||
testdir.makepyfile(confrest=
|
||||
"from py.plugin.pytest_restdoc import Project")
|
||||
for p in testdir.plugins:
|
||||
if p == globals():
|
||||
break
|
||||
else:
|
||||
testdir.plugins.append(globals())
|
||||
return testdir
|
||||
|
||||
def test_doctest_extra_exec(self, testdir):
|
||||
xtxt = testdir.maketxtfile(x="""
|
||||
hello::
|
||||
.. >>> raise ValueError
|
||||
>>> None
|
||||
""")
|
||||
reprec = testdir.inline_run(xtxt)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 1
|
||||
|
||||
def test_doctest_basic(self, testdir):
|
||||
xtxt = testdir.maketxtfile(x="""
|
||||
..
|
||||
>>> from os.path import abspath
|
||||
|
||||
hello world
|
||||
|
||||
>>> assert abspath
|
||||
>>> i=3
|
||||
>>> print (i)
|
||||
3
|
||||
|
||||
yes yes
|
||||
|
||||
>>> i
|
||||
3
|
||||
|
||||
end
|
||||
""")
|
||||
reprec = testdir.inline_run(xtxt)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 0
|
||||
assert passed + skipped == 2
|
||||
|
||||
def test_doctest_eol(self, testdir):
|
||||
ytxt = testdir.maketxtfile(y=".. >>> 1 + 1\r\n 2\r\n\r\n")
|
||||
reprec = testdir.inline_run(ytxt)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 0
|
||||
assert passed + skipped == 2
|
||||
|
||||
def test_doctest_indentation(self, testdir):
|
||||
footxt = testdir.maketxtfile(foo=
|
||||
'..\n >>> print ("foo\\n bar")\n foo\n bar\n')
|
||||
reprec = testdir.inline_run(footxt)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 0
|
||||
assert skipped + passed == 2
|
||||
|
||||
def test_js_ignore(self, testdir):
|
||||
xtxt = testdir.maketxtfile(xtxt="""
|
||||
`blah`_
|
||||
|
||||
.. _`blah`: javascript:some_function()
|
||||
""")
|
||||
reprec = testdir.inline_run(xtxt)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 0
|
||||
assert skipped + passed == 3
|
||||
|
||||
def test_pytest_doctest_prepare_content(self, testdir):
|
||||
l = []
|
||||
class MyPlugin:
|
||||
def pytest_doctest_prepare_content(self, content):
|
||||
l.append(content)
|
||||
return content.replace("False", "True")
|
||||
|
||||
testdir.plugins.append(MyPlugin())
|
||||
|
||||
xtxt = testdir.maketxtfile(x="""
|
||||
hello:
|
||||
|
||||
>>> 2 == 2
|
||||
False
|
||||
|
||||
""")
|
||||
reprec = testdir.inline_run(xtxt)
|
||||
assert len(l) == 1
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert passed >= 1
|
||||
assert not failed
|
||||
assert skipped <= 1
|
||||
170
testing/plugin/test_pytest_resultlog.py
Normal file
170
testing/plugin/test_pytest_resultlog.py
Normal file
@@ -0,0 +1,170 @@
|
||||
import py
|
||||
import os
|
||||
from py.plugin.pytest_resultlog import generic_path, ResultLog
|
||||
from py.impl.test.collect import Node, Item, FSCollector
|
||||
|
||||
def test_generic_path():
|
||||
p1 = Node('a')
|
||||
assert p1.fspath is None
|
||||
p2 = Node('B', parent=p1)
|
||||
p3 = Node('()', parent = p2)
|
||||
item = Item('c', parent = p3)
|
||||
|
||||
res = generic_path(item)
|
||||
assert res == 'a.B().c'
|
||||
|
||||
p0 = FSCollector('proj/test')
|
||||
p1 = FSCollector('proj/test/a', parent=p0)
|
||||
p2 = Node('B', parent=p1)
|
||||
p3 = Node('()', parent = p2)
|
||||
p4 = Node('c', parent=p3)
|
||||
item = Item('[1]', parent = p4)
|
||||
|
||||
res = generic_path(item)
|
||||
assert res == 'test/a:B().c[1]'
|
||||
|
||||
def test_write_log_entry():
|
||||
reslog = ResultLog(None, None)
|
||||
reslog.logfile = py.io.TextIO()
|
||||
reslog.write_log_entry('name', '.', '')
|
||||
entry = reslog.logfile.getvalue()
|
||||
assert entry[-1] == '\n'
|
||||
entry_lines = entry.splitlines()
|
||||
assert len(entry_lines) == 1
|
||||
assert entry_lines[0] == '. name'
|
||||
|
||||
reslog.logfile = py.io.TextIO()
|
||||
reslog.write_log_entry('name', 's', 'Skipped')
|
||||
entry = reslog.logfile.getvalue()
|
||||
assert entry[-1] == '\n'
|
||||
entry_lines = entry.splitlines()
|
||||
assert len(entry_lines) == 2
|
||||
assert entry_lines[0] == 's name'
|
||||
assert entry_lines[1] == ' Skipped'
|
||||
|
||||
reslog.logfile = py.io.TextIO()
|
||||
reslog.write_log_entry('name', 's', 'Skipped\n')
|
||||
entry = reslog.logfile.getvalue()
|
||||
assert entry[-1] == '\n'
|
||||
entry_lines = entry.splitlines()
|
||||
assert len(entry_lines) == 2
|
||||
assert entry_lines[0] == 's name'
|
||||
assert entry_lines[1] == ' Skipped'
|
||||
|
||||
reslog.logfile = py.io.TextIO()
|
||||
longrepr = ' tb1\n tb 2\nE tb3\nSome Error'
|
||||
reslog.write_log_entry('name', 'F', longrepr)
|
||||
entry = reslog.logfile.getvalue()
|
||||
assert entry[-1] == '\n'
|
||||
entry_lines = entry.splitlines()
|
||||
assert len(entry_lines) == 5
|
||||
assert entry_lines[0] == 'F name'
|
||||
assert entry_lines[1:] == [' '+line for line in longrepr.splitlines()]
|
||||
|
||||
|
||||
class TestWithFunctionIntegration:
|
||||
# XXX (hpk) i think that the resultlog plugin should
|
||||
# provide a Parser object so that one can remain
|
||||
# ignorant regarding formatting details.
|
||||
def getresultlog(self, testdir, arg):
|
||||
resultlog = testdir.tmpdir.join("resultlog")
|
||||
testdir.plugins.append("resultlog")
|
||||
args = ["--resultlog=%s" % resultlog] + [arg]
|
||||
testdir.runpytest(*args)
|
||||
return [x for x in resultlog.readlines(cr=0) if x]
|
||||
|
||||
def test_collection_report(self, testdir):
|
||||
ok = testdir.makepyfile(test_collection_ok="")
|
||||
skip = testdir.makepyfile(test_collection_skip="import py ; py.test.skip('hello')")
|
||||
fail = testdir.makepyfile(test_collection_fail="XXX")
|
||||
lines = self.getresultlog(testdir, ok)
|
||||
assert not lines
|
||||
|
||||
lines = self.getresultlog(testdir, skip)
|
||||
assert len(lines) == 2
|
||||
assert lines[0].startswith("S ")
|
||||
assert lines[0].endswith("test_collection_skip.py")
|
||||
assert lines[1].startswith(" ")
|
||||
assert lines[1].endswith("test_collection_skip.py:1: Skipped: 'hello'")
|
||||
|
||||
lines = self.getresultlog(testdir, fail)
|
||||
assert lines
|
||||
assert lines[0].startswith("F ")
|
||||
assert lines[0].endswith("test_collection_fail.py"), lines[0]
|
||||
for x in lines[1:]:
|
||||
assert x.startswith(" ")
|
||||
assert "XXX" in "".join(lines[1:])
|
||||
|
||||
def test_log_test_outcomes(self, testdir):
|
||||
mod = testdir.makepyfile(test_mod="""
|
||||
import py
|
||||
def test_pass(): pass
|
||||
def test_skip(): py.test.skip("hello")
|
||||
def test_fail(): raise ValueError("FAIL")
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_xfail(): raise ValueError("XFAIL")
|
||||
@py.test.mark.xfail
|
||||
def test_xpass(): pass
|
||||
|
||||
""")
|
||||
lines = self.getresultlog(testdir, mod)
|
||||
assert len(lines) >= 3
|
||||
assert lines[0].startswith(". ")
|
||||
assert lines[0].endswith("test_pass")
|
||||
assert lines[1].startswith("s "), lines[1]
|
||||
assert lines[1].endswith("test_skip")
|
||||
assert lines[2].find("hello") != -1
|
||||
|
||||
assert lines[3].startswith("F ")
|
||||
assert lines[3].endswith("test_fail")
|
||||
tb = "".join(lines[4:8])
|
||||
assert tb.find('raise ValueError("FAIL")') != -1
|
||||
|
||||
assert lines[8].startswith('x ')
|
||||
tb = "".join(lines[8:14])
|
||||
assert tb.find('raise ValueError("XFAIL")') != -1
|
||||
|
||||
assert lines[14].startswith('P ')
|
||||
assert len(lines) == 15
|
||||
|
||||
def test_internal_exception(self):
|
||||
# they are produced for example by a teardown failing
|
||||
# at the end of the run
|
||||
try:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
excinfo = py.code.ExceptionInfo()
|
||||
reslog = ResultLog(None, py.io.TextIO())
|
||||
reslog.pytest_internalerror(excinfo.getrepr())
|
||||
entry = reslog.logfile.getvalue()
|
||||
entry_lines = entry.splitlines()
|
||||
|
||||
assert entry_lines[0].startswith('! ')
|
||||
assert os.path.basename(__file__)[:-1] in entry_lines[0] #.py/.pyc
|
||||
assert entry_lines[-1][0] == ' '
|
||||
assert 'ValueError' in entry
|
||||
|
||||
def test_generic(testdir, LineMatcher):
|
||||
testdir.plugins.append("resultlog")
|
||||
testdir.makepyfile("""
|
||||
import py
|
||||
def test_pass():
|
||||
pass
|
||||
def test_fail():
|
||||
assert 0
|
||||
def test_skip():
|
||||
py.test.skip("")
|
||||
@py.test.mark.xfail
|
||||
def test_xfail():
|
||||
assert 0
|
||||
""")
|
||||
testdir.runpytest("--resultlog=result.log")
|
||||
lines = testdir.tmpdir.join("result.log").readlines(cr=0)
|
||||
LineMatcher(lines).fnmatch_lines([
|
||||
". *:test_pass",
|
||||
"F *:test_fail",
|
||||
"s *:test_skip",
|
||||
"x *:test_xfail",
|
||||
])
|
||||
|
||||
287
testing/plugin/test_pytest_runner.py
Normal file
287
testing/plugin/test_pytest_runner.py
Normal file
@@ -0,0 +1,287 @@
|
||||
import py
|
||||
from py.plugin import pytest_runner as runner
|
||||
from py.impl.code.code import ReprExceptionInfo
|
||||
|
||||
class TestSetupState:
|
||||
def test_setup(self, testdir):
|
||||
ss = runner.SetupState()
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
l = [1]
|
||||
ss.prepare(item)
|
||||
ss.addfinalizer(l.pop, colitem=item)
|
||||
assert l
|
||||
ss._pop_and_teardown()
|
||||
assert not l
|
||||
|
||||
def test_setup_scope_None(self, testdir):
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
ss = runner.SetupState()
|
||||
l = [1]
|
||||
ss.prepare(item)
|
||||
ss.addfinalizer(l.pop, colitem=None)
|
||||
assert l
|
||||
ss._pop_and_teardown()
|
||||
assert l
|
||||
ss._pop_and_teardown()
|
||||
assert l
|
||||
ss.teardown_all()
|
||||
assert not l
|
||||
|
||||
def test_teardown_exact_stack_empty(self, testdir):
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
ss = runner.SetupState()
|
||||
ss.teardown_exact(item)
|
||||
ss.teardown_exact(item)
|
||||
ss.teardown_exact(item)
|
||||
|
||||
class BaseFunctionalTests:
|
||||
def test_passfunction(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
rep = reports[1]
|
||||
assert rep.passed
|
||||
assert not rep.failed
|
||||
assert rep.shortrepr == "."
|
||||
assert not hasattr(rep, 'longrepr')
|
||||
|
||||
def test_failfunction(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
def test_func():
|
||||
assert 0
|
||||
""")
|
||||
rep = reports[1]
|
||||
assert not rep.passed
|
||||
assert not rep.skipped
|
||||
assert rep.failed
|
||||
assert rep.when == "call"
|
||||
assert isinstance(rep.longrepr, ReprExceptionInfo)
|
||||
assert str(rep.shortrepr) == "F"
|
||||
|
||||
def test_skipfunction(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def test_func():
|
||||
py.test.skip("hello")
|
||||
""")
|
||||
rep = reports[1]
|
||||
assert not rep.failed
|
||||
assert not rep.passed
|
||||
assert rep.skipped
|
||||
#assert rep.skipped.when == "call"
|
||||
#assert rep.skipped.when == "call"
|
||||
#assert rep.skipped == "%sreason == "hello"
|
||||
#assert rep.skipped.location.lineno == 3
|
||||
#assert rep.skipped.location.path
|
||||
#assert not rep.skipped.failurerepr
|
||||
|
||||
def test_skip_in_setup_function(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def setup_function(func):
|
||||
py.test.skip("hello")
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
print(reports)
|
||||
rep = reports[0]
|
||||
assert not rep.failed
|
||||
assert not rep.passed
|
||||
assert rep.skipped
|
||||
#assert rep.skipped.reason == "hello"
|
||||
#assert rep.skipped.location.lineno == 3
|
||||
#assert rep.skipped.location.lineno == 3
|
||||
assert len(reports) == 2
|
||||
assert reports[1].passed # teardown
|
||||
|
||||
def test_failure_in_setup_function(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def setup_function(func):
|
||||
raise ValueError(42)
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
rep = reports[0]
|
||||
assert not rep.skipped
|
||||
assert not rep.passed
|
||||
assert rep.failed
|
||||
assert rep.when == "setup"
|
||||
assert len(reports) == 2
|
||||
|
||||
def test_failure_in_teardown_function(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def teardown_function(func):
|
||||
raise ValueError(42)
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
print(reports)
|
||||
assert len(reports) == 3
|
||||
rep = reports[2]
|
||||
assert not rep.skipped
|
||||
assert not rep.passed
|
||||
assert rep.failed
|
||||
assert rep.when == "teardown"
|
||||
assert rep.longrepr.reprcrash.lineno == 3
|
||||
assert rep.longrepr.reprtraceback.reprentries
|
||||
|
||||
def test_custom_failure_repr(self, testdir):
|
||||
testdir.makepyfile(conftest="""
|
||||
import py
|
||||
class Function(py.test.collect.Function):
|
||||
def repr_failure(self, excinfo):
|
||||
return "hello"
|
||||
""")
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def test_func():
|
||||
assert 0
|
||||
""")
|
||||
rep = reports[1]
|
||||
assert not rep.skipped
|
||||
assert not rep.passed
|
||||
assert rep.failed
|
||||
#assert rep.outcome.when == "call"
|
||||
#assert rep.failed.where.lineno == 3
|
||||
#assert rep.failed.where.path.basename == "test_func.py"
|
||||
#assert rep.failed.failurerepr == "hello"
|
||||
|
||||
def test_failure_in_setup_function_ignores_custom_repr(self, testdir):
|
||||
testdir.makepyfile(conftest="""
|
||||
import py
|
||||
class Function(py.test.collect.Function):
|
||||
def repr_failure(self, excinfo):
|
||||
assert 0
|
||||
""")
|
||||
reports = testdir.runitem("""
|
||||
import py
|
||||
def setup_function(func):
|
||||
raise ValueError(42)
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
assert len(reports) == 2
|
||||
rep = reports[0]
|
||||
print(rep)
|
||||
assert not rep.skipped
|
||||
assert not rep.passed
|
||||
assert rep.failed
|
||||
#assert rep.outcome.when == "setup"
|
||||
#assert rep.outcome.where.lineno == 3
|
||||
#assert rep.outcome.where.path.basename == "test_func.py"
|
||||
#assert instanace(rep.failed.failurerepr, PythonFailureRepr)
|
||||
|
||||
def test_systemexit_does_not_bail_out(self, testdir):
|
||||
try:
|
||||
reports = testdir.runitem("""
|
||||
def test_func():
|
||||
raise SystemExit(42)
|
||||
""")
|
||||
except SystemExit:
|
||||
py.test.fail("runner did not catch SystemExit")
|
||||
rep = reports[1]
|
||||
assert rep.failed
|
||||
assert rep.when == "call"
|
||||
|
||||
def test_exit_propagates(self, testdir):
|
||||
from py.impl.test.outcome import Exit
|
||||
try:
|
||||
testdir.runitem("""
|
||||
from py.impl.test.outcome import Exit
|
||||
def test_func():
|
||||
raise Exit()
|
||||
""")
|
||||
except Exit:
|
||||
pass
|
||||
else:
|
||||
py.test.fail("did not raise")
|
||||
|
||||
class TestExecutionNonForked(BaseFunctionalTests):
|
||||
def getrunner(self):
|
||||
def f(item):
|
||||
return runner.runtestprotocol(item, log=False)
|
||||
return f
|
||||
|
||||
def test_keyboardinterrupt_propagates(self, testdir):
|
||||
from py.impl.test.outcome import Exit
|
||||
try:
|
||||
testdir.runitem("""
|
||||
def test_func():
|
||||
raise KeyboardInterrupt("fake")
|
||||
""")
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
else:
|
||||
py.test.fail("did not raise")
|
||||
|
||||
class TestExecutionForked(BaseFunctionalTests):
|
||||
pytestmark = py.test.mark.skipif("not hasattr(os, 'fork')")
|
||||
|
||||
def getrunner(self):
|
||||
return runner.forked_run_report
|
||||
|
||||
def test_suicide(self, testdir):
|
||||
reports = testdir.runitem("""
|
||||
def test_func():
|
||||
import os
|
||||
os.kill(os.getpid(), 15)
|
||||
""")
|
||||
rep = reports[0]
|
||||
assert rep.failed
|
||||
assert rep.when == "???"
|
||||
|
||||
class TestCollectionReports:
|
||||
def test_collect_result(self, testdir):
|
||||
col = testdir.getmodulecol("""
|
||||
def test_func1():
|
||||
pass
|
||||
class TestClass:
|
||||
pass
|
||||
""")
|
||||
rep = runner.pytest_make_collect_report(col)
|
||||
assert not rep.failed
|
||||
assert not rep.skipped
|
||||
assert rep.passed
|
||||
res = rep.result
|
||||
assert len(res) == 2
|
||||
assert res[0].name == "test_func1"
|
||||
assert res[1].name == "TestClass"
|
||||
|
||||
def test_skip_at_module_scope(self, testdir):
|
||||
col = testdir.getmodulecol("""
|
||||
import py
|
||||
py.test.skip("hello")
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
rep = runner.pytest_make_collect_report(col)
|
||||
assert not rep.failed
|
||||
assert not rep.passed
|
||||
assert rep.skipped
|
||||
|
||||
@py.test.mark.skipif("not hasattr(os, 'fork')")
|
||||
def test_functional_boxed(testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
import os
|
||||
def test_function():
|
||||
os.kill(os.getpid(), 15)
|
||||
""")
|
||||
result = testdir.runpytest(p1, "--boxed")
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*CRASHED*",
|
||||
"*1 failed*"
|
||||
])
|
||||
|
||||
def test_callinfo():
|
||||
ci = runner.CallInfo(lambda: 0, '123')
|
||||
assert ci.when == "123"
|
||||
assert ci.result == 0
|
||||
assert "result" in repr(ci)
|
||||
ci = runner.CallInfo(lambda: 0/0, '123')
|
||||
assert ci.when == "123"
|
||||
assert not hasattr(ci, 'result')
|
||||
assert ci.excinfo
|
||||
assert "exc" in repr(ci)
|
||||
136
testing/plugin/test_pytest_runner_xunit.py
Normal file
136
testing/plugin/test_pytest_runner_xunit.py
Normal file
@@ -0,0 +1,136 @@
|
||||
#
|
||||
# test correct setup/teardowns at
|
||||
# module, class, and instance level
|
||||
|
||||
def test_module_and_function_setup(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
modlevel = []
|
||||
def setup_module(module):
|
||||
assert not modlevel
|
||||
module.modlevel.append(42)
|
||||
|
||||
def teardown_module(module):
|
||||
modlevel.pop()
|
||||
|
||||
def setup_function(function):
|
||||
function.answer = 17
|
||||
|
||||
def teardown_function(function):
|
||||
del function.answer
|
||||
|
||||
def test_modlevel():
|
||||
assert modlevel[0] == 42
|
||||
assert test_modlevel.answer == 17
|
||||
|
||||
class TestFromClass:
|
||||
def test_module(self):
|
||||
assert modlevel[0] == 42
|
||||
assert not hasattr(test_modlevel, 'answer')
|
||||
""")
|
||||
rep = reprec.matchreport("test_modlevel")
|
||||
assert rep.passed
|
||||
rep = reprec.matchreport("test_module")
|
||||
assert rep.passed
|
||||
|
||||
def test_class_setup(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
class TestSimpleClassSetup:
|
||||
clslevel = []
|
||||
def setup_class(cls):
|
||||
cls.clslevel.append(23)
|
||||
|
||||
def teardown_class(cls):
|
||||
cls.clslevel.pop()
|
||||
|
||||
def test_classlevel(self):
|
||||
assert self.clslevel[0] == 23
|
||||
|
||||
class TestInheritedClassSetupStillWorks(TestSimpleClassSetup):
|
||||
def test_classlevel_anothertime(self):
|
||||
assert self.clslevel == [23]
|
||||
|
||||
def test_cleanup():
|
||||
assert not TestSimpleClassSetup.clslevel
|
||||
assert not TestInheritedClassSetupStillWorks.clslevel
|
||||
""")
|
||||
reprec.assertoutcome(passed=1+2+1)
|
||||
|
||||
|
||||
def test_method_setup(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
class TestSetupMethod:
|
||||
def setup_method(self, meth):
|
||||
self.methsetup = meth
|
||||
def teardown_method(self, meth):
|
||||
del self.methsetup
|
||||
|
||||
def test_some(self):
|
||||
assert self.methsetup == self.test_some
|
||||
|
||||
def test_other(self):
|
||||
assert self.methsetup == self.test_other
|
||||
""")
|
||||
reprec.assertoutcome(passed=2)
|
||||
|
||||
def test_method_generator_setup(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
class TestSetupTeardownOnInstance:
|
||||
def setup_class(cls):
|
||||
cls.classsetup = True
|
||||
|
||||
def setup_method(self, method):
|
||||
self.methsetup = method
|
||||
|
||||
def test_generate(self):
|
||||
assert self.classsetup
|
||||
assert self.methsetup == self.test_generate
|
||||
yield self.generated, 5
|
||||
yield self.generated, 2
|
||||
|
||||
def generated(self, value):
|
||||
assert self.classsetup
|
||||
assert self.methsetup == self.test_generate
|
||||
assert value == 5
|
||||
""")
|
||||
reprec.assertoutcome(passed=1, failed=1)
|
||||
|
||||
def test_func_generator_setup(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
import sys
|
||||
|
||||
def setup_module(mod):
|
||||
print ("setup_module")
|
||||
mod.x = []
|
||||
|
||||
def setup_function(fun):
|
||||
print ("setup_function")
|
||||
x.append(1)
|
||||
|
||||
def teardown_function(fun):
|
||||
print ("teardown_function")
|
||||
x.pop()
|
||||
|
||||
def test_one():
|
||||
assert x == [1]
|
||||
def check():
|
||||
print ("check")
|
||||
sys.stderr.write("e\\n")
|
||||
assert x == [1]
|
||||
yield check
|
||||
assert x == [1]
|
||||
""")
|
||||
rep = reprec.matchreport("test_one", names="pytest_runtest_logreport")
|
||||
assert rep.passed
|
||||
|
||||
def test_method_setup_uses_fresh_instances(testdir):
|
||||
reprec = testdir.inline_runsource("""
|
||||
class TestSelfState1:
|
||||
memory = []
|
||||
def test_hello(self):
|
||||
self.memory.append(self)
|
||||
|
||||
def test_afterhello(self):
|
||||
assert self != self.memory[0]
|
||||
""")
|
||||
reprec.assertoutcome(passed=2, failed=0)
|
||||
|
||||
175
testing/plugin/test_pytest_skipping.py
Normal file
175
testing/plugin/test_pytest_skipping.py
Normal file
@@ -0,0 +1,175 @@
|
||||
import py
|
||||
|
||||
def test_xfail_not_report_default(testdir):
|
||||
p = testdir.makepyfile(test_one="""
|
||||
import py
|
||||
@py.test.mark.xfail
|
||||
def test_this():
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p, '-v')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*1 expected failures*--report=xfailed*",
|
||||
])
|
||||
|
||||
def test_skip_not_report_default(testdir):
|
||||
p = testdir.makepyfile(test_one="""
|
||||
import py
|
||||
def test_this():
|
||||
py.test.skip("hello")
|
||||
""")
|
||||
result = testdir.runpytest(p, '-v')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*1 skipped*--report=skipped*",
|
||||
])
|
||||
|
||||
def test_xfail_decorator(testdir):
|
||||
p = testdir.makepyfile(test_one="""
|
||||
import py
|
||||
@py.test.mark.xfail
|
||||
def test_this():
|
||||
assert 0
|
||||
|
||||
@py.test.mark.xfail
|
||||
def test_that():
|
||||
assert 1
|
||||
""")
|
||||
result = testdir.runpytest(p, '--report=xfailed')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*expected failures*",
|
||||
"*test_one.test_this*test_one.py:4*",
|
||||
"*UNEXPECTEDLY PASSING*",
|
||||
"*test_that*",
|
||||
"*1 xfailed*"
|
||||
])
|
||||
assert result.ret == 1
|
||||
|
||||
def test_xfail_at_module(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
pytestmark = py.test.mark.xfail('True')
|
||||
def test_intentional_xfail():
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p, '--report=xfailed')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*expected failures*",
|
||||
"*test_intentional_xfail*:4*",
|
||||
"*1 xfailed*"
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
def test_xfail_evalfalse_but_fails(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
@py.test.mark.xfail('False')
|
||||
def test_fail():
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p, '--report=xfailed')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*test_xfail_evalfalse_but_fails*:4*",
|
||||
"*1 failed*"
|
||||
])
|
||||
assert result.ret == 1
|
||||
|
||||
def test_skipif_decorator(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
@py.test.mark.skipif("hasattr(sys, 'platform')")
|
||||
def test_that():
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p, '--report=skipped')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*Skipped*platform*",
|
||||
"*1 skipped*"
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
def test_skipif_class(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
|
||||
class TestClass:
|
||||
pytestmark = py.test.mark.skipif("True")
|
||||
def test_that(self):
|
||||
assert 0
|
||||
def test_though(self):
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p)
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*2 skipped*"
|
||||
])
|
||||
|
||||
def test_evalexpression_cls_config_example(testdir):
|
||||
from py.plugin.pytest_skipping import evalexpression
|
||||
item, = testdir.getitems("""
|
||||
import py
|
||||
class TestClass:
|
||||
pytestmark = py.test.mark.skipif("config._hackxyz")
|
||||
def test_func(self):
|
||||
pass
|
||||
""")
|
||||
item.config._hackxyz = 3
|
||||
x, y = evalexpression(item, 'skipif')
|
||||
assert x == 'config._hackxyz'
|
||||
assert y == 3
|
||||
|
||||
def test_skip_reasons_folding():
|
||||
from py.plugin import pytest_runner as runner
|
||||
from py.plugin.pytest_skipping import folded_skips
|
||||
class longrepr:
|
||||
class reprcrash:
|
||||
path = 'xyz'
|
||||
lineno = 3
|
||||
message = "justso"
|
||||
|
||||
ev1 = runner.CollectReport(None, None)
|
||||
ev1.when = "execute"
|
||||
ev1.skipped = True
|
||||
ev1.longrepr = longrepr
|
||||
|
||||
ev2 = runner.ItemTestReport(None, excinfo=longrepr)
|
||||
ev2.skipped = True
|
||||
|
||||
l = folded_skips([ev1, ev2])
|
||||
assert len(l) == 1
|
||||
num, fspath, lineno, reason = l[0]
|
||||
assert num == 2
|
||||
assert fspath == longrepr.reprcrash.path
|
||||
assert lineno == longrepr.reprcrash.lineno
|
||||
assert reason == longrepr.reprcrash.message
|
||||
|
||||
def test_skipped_reasons_functional(testdir):
|
||||
testdir.makepyfile(
|
||||
test_one="""
|
||||
from conftest import doskip
|
||||
def setup_function(func):
|
||||
doskip()
|
||||
def test_func():
|
||||
pass
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
doskip()
|
||||
""",
|
||||
test_two = """
|
||||
from conftest import doskip
|
||||
doskip()
|
||||
""",
|
||||
conftest = """
|
||||
import py
|
||||
def doskip():
|
||||
py.test.skip('test')
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest('--report=skipped')
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*test_one.py ss",
|
||||
"*test_two.py S",
|
||||
"___* skipped test summary *_",
|
||||
"*conftest.py:3: *3* Skipped: 'test'",
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
589
testing/plugin/test_pytest_terminal.py
Normal file
589
testing/plugin/test_pytest_terminal.py
Normal file
@@ -0,0 +1,589 @@
|
||||
"""
|
||||
terminal reporting of the full testing process.
|
||||
"""
|
||||
import py
|
||||
import sys
|
||||
try:
|
||||
import execnet
|
||||
except ImportError:
|
||||
execnet = None
|
||||
|
||||
# ===============================================================================
|
||||
# plugin tests
|
||||
#
|
||||
# ===============================================================================
|
||||
|
||||
from py.plugin.pytest_terminal import TerminalReporter, \
|
||||
CollectonlyReporter, repr_pythonversion, getreportopt
|
||||
from py.plugin import pytest_runner as runner
|
||||
|
||||
def basic_run_report(item):
|
||||
return runner.call_and_report(item, "call", log=False)
|
||||
|
||||
class Option:
|
||||
def __init__(self, verbose=False, dist=None):
|
||||
self.verbose = verbose
|
||||
self.dist = dist
|
||||
def _getcmdargs(self):
|
||||
l = []
|
||||
if self.verbose:
|
||||
l.append('-v')
|
||||
if self.dist:
|
||||
l.append('--dist=%s' % self.dist)
|
||||
l.append('--tx=popen')
|
||||
return l
|
||||
def _getcmdstring(self):
|
||||
return " ".join(self._getcmdargs())
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
if "option" in metafunc.funcargnames:
|
||||
metafunc.addcall(
|
||||
id="default",
|
||||
funcargs={'option': Option(verbose=False)}
|
||||
)
|
||||
metafunc.addcall(
|
||||
id="verbose",
|
||||
funcargs={'option': Option(verbose=True)}
|
||||
)
|
||||
nodist = getattr(metafunc.function, 'nodist', False)
|
||||
if execnet and not nodist:
|
||||
metafunc.addcall(
|
||||
id="verbose-dist",
|
||||
funcargs={'option': Option(dist='each', verbose=True)}
|
||||
)
|
||||
|
||||
class TestTerminal:
|
||||
def test_pass_skip_fail(self, testdir, option):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
def test_ok():
|
||||
pass
|
||||
def test_skip():
|
||||
py.test.skip("xx")
|
||||
def test_func():
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(*option._getcmdargs())
|
||||
if option.verbose:
|
||||
if not option.dist:
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_pass_skip_fail.py:2: *test_ok*PASS*",
|
||||
"*test_pass_skip_fail.py:4: *test_skip*SKIP*",
|
||||
"*test_pass_skip_fail.py:6: *test_func*FAIL*",
|
||||
])
|
||||
else:
|
||||
expected = [
|
||||
"*PASS*test_pass_skip_fail.py:2: *test_ok*",
|
||||
"*SKIP*test_pass_skip_fail.py:4: *test_skip*",
|
||||
"*FAIL*test_pass_skip_fail.py:6: *test_func*",
|
||||
]
|
||||
for line in expected:
|
||||
result.stdout.fnmatch_lines([line])
|
||||
else:
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_pass_skip_fail.py .sF"
|
||||
])
|
||||
result.stdout.fnmatch_lines([
|
||||
" def test_func():",
|
||||
"> assert 0",
|
||||
"E assert 0",
|
||||
])
|
||||
|
||||
def test_collect_fail(self, testdir, option):
|
||||
p = testdir.makepyfile("import xyz")
|
||||
result = testdir.runpytest(*option._getcmdargs())
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_collect_fail.py E*",
|
||||
"> import xyz",
|
||||
"E ImportError: No module named xyz",
|
||||
"*1 error*",
|
||||
])
|
||||
|
||||
def test_internalerror(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol("def test_one(): pass")
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
excinfo = py.test.raises(ValueError, "raise ValueError('hello')")
|
||||
rep.pytest_internalerror(excinfo.getrepr())
|
||||
linecomp.assert_contains_lines([
|
||||
"INTERNALERROR> *raise ValueError*"
|
||||
])
|
||||
|
||||
def test_gwmanage_events(self, testdir, linecomp):
|
||||
execnet = py.test.importorskip("execnet")
|
||||
modcol = testdir.getmodulecol("""
|
||||
def test_one():
|
||||
pass
|
||||
""", configargs=("-v",))
|
||||
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
class gw1:
|
||||
id = "X1"
|
||||
spec = execnet.XSpec("popen")
|
||||
class gw2:
|
||||
id = "X2"
|
||||
spec = execnet.XSpec("popen")
|
||||
class rinfo:
|
||||
version_info = (2, 5, 1, 'final', 0)
|
||||
executable = "hello"
|
||||
platform = "xyz"
|
||||
cwd = "qwe"
|
||||
|
||||
rep.pytest_gwmanage_newgateway(gw1, rinfo)
|
||||
linecomp.assert_contains_lines([
|
||||
"X1*popen*xyz*2.5*"
|
||||
])
|
||||
|
||||
rep.pytest_gwmanage_rsyncstart(source="hello", gateways=[gw1, gw2])
|
||||
linecomp.assert_contains_lines([
|
||||
"rsyncstart: hello -> X1, X2"
|
||||
])
|
||||
rep.pytest_gwmanage_rsyncfinish(source="hello", gateways=[gw1, gw2])
|
||||
linecomp.assert_contains_lines([
|
||||
"rsyncfinish: hello -> X1, X2"
|
||||
])
|
||||
|
||||
def test_writeline(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol("def test_one(): pass")
|
||||
stringio = py.io.TextIO()
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
rep.write_fspath_result(py.path.local("xy.py"), '.')
|
||||
rep.write_line("hello world")
|
||||
lines = linecomp.stringio.getvalue().split('\n')
|
||||
assert not lines[0]
|
||||
assert lines[1].endswith("xy.py .")
|
||||
assert lines[2] == "hello world"
|
||||
|
||||
def test_looponfailreport(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol("""
|
||||
def test_fail():
|
||||
assert 0
|
||||
def test_fail2():
|
||||
raise ValueError()
|
||||
""")
|
||||
rep = TerminalReporter(modcol.config, file=linecomp.stringio)
|
||||
reports = [basic_run_report(x) for x in modcol.collect()]
|
||||
rep.pytest_looponfailinfo(reports, [modcol.config.topdir])
|
||||
linecomp.assert_contains_lines([
|
||||
"*test_looponfailreport.py:2: assert 0",
|
||||
"*test_looponfailreport.py:4: ValueError*",
|
||||
"*waiting*",
|
||||
"*%s*" % (modcol.config.topdir),
|
||||
])
|
||||
|
||||
def test_tb_option(self, testdir, option):
|
||||
p = testdir.makepyfile("""
|
||||
import py
|
||||
def g():
|
||||
raise IndexError
|
||||
def test_func():
|
||||
print (6*7)
|
||||
g() # --calling--
|
||||
""")
|
||||
for tbopt in ["long", "short", "no"]:
|
||||
print('testing --tb=%s...' % tbopt)
|
||||
result = testdir.runpytest('--tb=%s' % tbopt)
|
||||
s = result.stdout.str()
|
||||
if tbopt == "long":
|
||||
assert 'print (6*7)' in s
|
||||
else:
|
||||
assert 'print (6*7)' not in s
|
||||
if tbopt != "no":
|
||||
assert '--calling--' in s
|
||||
assert 'IndexError' in s
|
||||
else:
|
||||
assert 'FAILURES' not in s
|
||||
assert '--calling--' not in s
|
||||
assert 'IndexError' not in s
|
||||
|
||||
def test_show_path_before_running_test(self, testdir, linecomp):
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
tr = TerminalReporter(item.config, file=linecomp.stringio)
|
||||
item.config.pluginmanager.register(tr)
|
||||
tr.config.hook.pytest_itemstart(item=item)
|
||||
linecomp.assert_contains_lines([
|
||||
"*test_show_path_before_running_test.py*"
|
||||
])
|
||||
|
||||
def test_itemreport_reportinfo(self, testdir, linecomp):
|
||||
testdir.makeconftest("""
|
||||
import py
|
||||
class Function(py.test.collect.Function):
|
||||
def reportinfo(self):
|
||||
return "ABCDE", 42, "custom"
|
||||
""")
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
tr = TerminalReporter(item.config, file=linecomp.stringio)
|
||||
item.config.pluginmanager.register(tr)
|
||||
tr.config.option.verbose = True
|
||||
tr.config.hook.pytest_itemstart(item=item)
|
||||
linecomp.assert_contains_lines([
|
||||
"*ABCDE:43: custom*"
|
||||
])
|
||||
|
||||
def test_itemreport_pytest_report_iteminfo(self, testdir, linecomp):
|
||||
item = testdir.getitem("def test_func(): pass")
|
||||
class Plugin:
|
||||
def pytest_report_iteminfo(self, item):
|
||||
return "FGHJ", 42, "custom"
|
||||
item.config.pluginmanager.register(Plugin())
|
||||
tr = TerminalReporter(item.config, file=linecomp.stringio)
|
||||
item.config.pluginmanager.register(tr)
|
||||
tr.config.option.verbose = True
|
||||
tr.config.hook.pytest_itemstart(item=item)
|
||||
linecomp.assert_contains_lines([
|
||||
"*FGHJ:43: custom*"
|
||||
])
|
||||
|
||||
def test_itemreport_subclasses_show_subclassed_file(self, testdir):
|
||||
p1 = testdir.makepyfile(test_p1="""
|
||||
class BaseTests:
|
||||
def test_p1(self):
|
||||
pass
|
||||
class TestClass(BaseTests):
|
||||
pass
|
||||
""")
|
||||
p2 = testdir.makepyfile(test_p2="""
|
||||
from test_p1 import BaseTests
|
||||
class TestMore(BaseTests):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest(p2)
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*test_p2.py .",
|
||||
"*1 passed*",
|
||||
])
|
||||
result = testdir.runpytest("-v", p2)
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_p2.py <- *test_p1.py:2: TestMore.test_p1*",
|
||||
])
|
||||
|
||||
def test_keyboard_interrupt_dist(self, testdir, option):
|
||||
p = testdir.makepyfile("""
|
||||
raise KeyboardInterrupt
|
||||
""")
|
||||
result = testdir.runpytest(*option._getcmdargs())
|
||||
assert result.ret == 2
|
||||
result.stdout.fnmatch_lines(['*KEYBOARD INTERRUPT*'])
|
||||
|
||||
@py.test.mark.nodist
|
||||
def test_keyboard_interrupt(self, testdir, option):
|
||||
p = testdir.makepyfile("""
|
||||
def test_foobar():
|
||||
assert 0
|
||||
def test_spamegg():
|
||||
import py; py.test.skip('skip me please!')
|
||||
def test_interrupt_me():
|
||||
raise KeyboardInterrupt # simulating the user
|
||||
""")
|
||||
|
||||
result = testdir.runpytest(*option._getcmdargs())
|
||||
result.stdout.fnmatch_lines([
|
||||
" def test_foobar():",
|
||||
"> assert 0",
|
||||
"E assert 0",
|
||||
"*_keyboard_interrupt.py:6: KeyboardInterrupt*",
|
||||
])
|
||||
if option.verbose:
|
||||
result.stdout.fnmatch_lines([
|
||||
"*raise KeyboardInterrupt # simulating the user*",
|
||||
])
|
||||
result.stdout.fnmatch_lines(['*KEYBOARD INTERRUPT*'])
|
||||
|
||||
|
||||
class TestCollectonly:
|
||||
def test_collectonly_basic(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol(configargs=['--collectonly'], source="""
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
rep = CollectonlyReporter(modcol.config, out=linecomp.stringio)
|
||||
modcol.config.pluginmanager.register(rep)
|
||||
indent = rep.indent
|
||||
rep.config.hook.pytest_collectstart(collector=modcol)
|
||||
linecomp.assert_contains_lines([
|
||||
"<Module 'test_collectonly_basic.py'>"
|
||||
])
|
||||
item = modcol.join("test_func")
|
||||
rep.config.hook.pytest_itemstart(item=item)
|
||||
linecomp.assert_contains_lines([
|
||||
" <Function 'test_func'>",
|
||||
])
|
||||
rep.config.hook.pytest_collectreport(
|
||||
report=runner.CollectReport(modcol, [], excinfo=None))
|
||||
assert rep.indent == indent
|
||||
|
||||
def test_collectonly_skipped_module(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol(configargs=['--collectonly'], source="""
|
||||
import py
|
||||
py.test.skip("nomod")
|
||||
""")
|
||||
rep = CollectonlyReporter(modcol.config, out=linecomp.stringio)
|
||||
modcol.config.pluginmanager.register(rep)
|
||||
cols = list(testdir.genitems([modcol]))
|
||||
assert len(cols) == 0
|
||||
linecomp.assert_contains_lines("""
|
||||
<Module 'test_collectonly_skipped_module.py'>
|
||||
!!! Skipped: 'nomod' !!!
|
||||
""")
|
||||
|
||||
def test_collectonly_failed_module(self, testdir, linecomp):
|
||||
modcol = testdir.getmodulecol(configargs=['--collectonly'], source="""
|
||||
raise ValueError(0)
|
||||
""")
|
||||
rep = CollectonlyReporter(modcol.config, out=linecomp.stringio)
|
||||
modcol.config.pluginmanager.register(rep)
|
||||
cols = list(testdir.genitems([modcol]))
|
||||
assert len(cols) == 0
|
||||
linecomp.assert_contains_lines("""
|
||||
<Module 'test_collectonly_failed_module.py'>
|
||||
!!! ValueError: 0 !!!
|
||||
""")
|
||||
|
||||
def test_collectonly_fatal(self, testdir):
|
||||
p1 = testdir.makeconftest("""
|
||||
def pytest_collectstart(collector):
|
||||
assert 0, "urgs"
|
||||
""")
|
||||
result = testdir.runpytest("--collectonly")
|
||||
result.stdout.fnmatch_lines([
|
||||
"*INTERNAL*args*"
|
||||
])
|
||||
assert result.ret == 3
|
||||
|
||||
def test_collectonly_simple(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_func1():
|
||||
pass
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest("--collectonly", p)
|
||||
stderr = result.stderr.str().strip()
|
||||
#assert stderr.startswith("inserting into sys.path")
|
||||
assert result.ret == 0
|
||||
extra = result.stdout.fnmatch_lines(py.code.Source("""
|
||||
<Module '*.py'>
|
||||
<Function 'test_func1'*>
|
||||
<Class 'TestClass'>
|
||||
<Instance '()'>
|
||||
<Function 'test_method'*>
|
||||
""").strip())
|
||||
|
||||
def test_collectonly_error(self, testdir):
|
||||
p = testdir.makepyfile("import Errlkjqweqwe")
|
||||
result = testdir.runpytest("--collectonly", p)
|
||||
stderr = result.stderr.str().strip()
|
||||
assert stderr.startswith("inserting into sys.path")
|
||||
assert result.ret == 1
|
||||
extra = result.stdout.fnmatch_lines(py.code.Source("""
|
||||
<Module '*.py'>
|
||||
*ImportError*
|
||||
!!!*failures*!!!
|
||||
*test_collectonly_error.py:1*
|
||||
""").strip())
|
||||
|
||||
|
||||
def test_repr_python_version(monkeypatch):
|
||||
monkeypatch.setattr(sys, 'version_info', (2, 5, 1, 'final', 0))
|
||||
assert repr_pythonversion() == "2.5.1-final-0"
|
||||
py.std.sys.version_info = x = (2,3)
|
||||
assert repr_pythonversion() == str(x)
|
||||
|
||||
class TestFixtureReporting:
|
||||
def test_setup_fixture_error(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def setup_function(function):
|
||||
print ("setup func")
|
||||
assert 0
|
||||
def test_nada():
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*ERROR at setup of test_nada*",
|
||||
"*setup_function(function):*",
|
||||
"*setup func*",
|
||||
"*assert 0*",
|
||||
"*1 error*",
|
||||
])
|
||||
assert result.ret != 0
|
||||
|
||||
def test_teardown_fixture_error(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_nada():
|
||||
pass
|
||||
def teardown_function(function):
|
||||
print ("teardown func")
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*ERROR at teardown*",
|
||||
"*teardown_function(function):*",
|
||||
"*assert 0*",
|
||||
"*Captured stdout*",
|
||||
"*teardown func*",
|
||||
"*1 passed*1 error*",
|
||||
])
|
||||
|
||||
def test_teardown_fixture_error_and_test_failure(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
def test_fail():
|
||||
assert 0, "failingfunc"
|
||||
|
||||
def teardown_function(function):
|
||||
print ("teardown func")
|
||||
assert False
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines([
|
||||
"*ERROR at teardown of test_fail*",
|
||||
"*teardown_function(function):*",
|
||||
"*assert False*",
|
||||
"*Captured stdout*",
|
||||
"*teardown func*",
|
||||
|
||||
"*test_fail*",
|
||||
"*def test_fail():",
|
||||
"*failingfunc*",
|
||||
"*1 failed*1 error*",
|
||||
])
|
||||
|
||||
class TestTerminalFunctional:
|
||||
def test_deselected(self, testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
def test_one():
|
||||
pass
|
||||
def test_two():
|
||||
pass
|
||||
def test_three():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest("-k", "test_two:", testpath)
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*test_deselected.py ..",
|
||||
"=* 1 test*deselected by 'test_two:'*=",
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
def test_no_skip_summary_if_failure(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import py
|
||||
def test_ok():
|
||||
pass
|
||||
def test_fail():
|
||||
assert 0
|
||||
def test_skip():
|
||||
py.test.skip("dontshow")
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert result.stdout.str().find("skip test summary") == -1
|
||||
assert result.ret == 1
|
||||
|
||||
def test_passes(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
def test_passes():
|
||||
pass
|
||||
class TestClass:
|
||||
def test_method(self):
|
||||
pass
|
||||
""")
|
||||
old = p1.dirpath().chdir()
|
||||
try:
|
||||
result = testdir.runpytest()
|
||||
finally:
|
||||
old.chdir()
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"test_passes.py ..",
|
||||
"* 2 pass*",
|
||||
])
|
||||
assert result.ret == 0
|
||||
|
||||
def test_header_trailer_info(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
def test_passes():
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
verinfo = ".".join(map(str, py.std.sys.version_info[:3]))
|
||||
extra = result.stdout.fnmatch_lines([
|
||||
"*===== test session starts ====*",
|
||||
"python: platform %s -- Python %s*" %(
|
||||
py.std.sys.platform, verinfo), # , py.std.sys.executable),
|
||||
"*test_header_trailer_info.py .",
|
||||
"=* 1 passed in *.[0-9][0-9] seconds *=",
|
||||
])
|
||||
|
||||
def test_showlocals(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
def test_showlocals():
|
||||
x = 3
|
||||
y = "x" * 5000
|
||||
assert 0
|
||||
""")
|
||||
result = testdir.runpytest(p1, '-l')
|
||||
result.stdout.fnmatch_lines([
|
||||
#"_ _ * Locals *",
|
||||
"x* = 3",
|
||||
"y* = 'xxxxxx*"
|
||||
])
|
||||
|
||||
def test_verbose_reporting(self, testdir):
|
||||
p1 = testdir.makepyfile("""
|
||||
import py
|
||||
def test_fail():
|
||||
raise ValueError()
|
||||
def test_pass():
|
||||
pass
|
||||
class TestClass:
|
||||
def test_skip(self):
|
||||
py.test.skip("hello")
|
||||
def test_gen():
|
||||
def check(x):
|
||||
assert x == 1
|
||||
yield check, 0
|
||||
""")
|
||||
result = testdir.runpytest(p1, '-v')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*test_verbose_reporting.py:2: test_fail*FAIL*",
|
||||
"*test_verbose_reporting.py:4: test_pass*PASS*",
|
||||
"*test_verbose_reporting.py:7: TestClass.test_skip*SKIP*",
|
||||
"*test_verbose_reporting.py:10: test_gen*FAIL*",
|
||||
])
|
||||
assert result.ret == 1
|
||||
if execnet:
|
||||
result = testdir.runpytest(p1, '-v', '-n 1')
|
||||
result.stdout.fnmatch_lines([
|
||||
"*FAIL*test_verbose_reporting.py:2: test_fail*",
|
||||
])
|
||||
assert result.ret == 1
|
||||
|
||||
|
||||
def test_getreportopt():
|
||||
assert getreportopt(None) == {}
|
||||
assert getreportopt("hello") == {'hello': True}
|
||||
assert getreportopt("hello, world") == dict(hello=True, world=True)
|
||||
assert getreportopt("nohello") == dict(hello=False)
|
||||
|
||||
def test_terminalreporter_reportopt_conftestsetting(testdir):
|
||||
testdir.makeconftest("option_report = 'skipped'")
|
||||
p = testdir.makepyfile("""
|
||||
def pytest_funcarg__tr(request):
|
||||
tr = request.config.pluginmanager.getplugin("terminalreporter")
|
||||
return tr
|
||||
def test_opt(tr):
|
||||
assert tr.hasopt('skipped')
|
||||
assert not tr.hasopt('qwe')
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*1 passed*"
|
||||
])
|
||||
def test_trace_reporting(self, testdir):
|
||||
result = testdir.runpytest("--trace")
|
||||
assert result.stdout.fnmatch_lines([
|
||||
"*active plugins*"
|
||||
])
|
||||
assert result.ret == 0
|
||||
9
testing/plugin/test_pytest_tmpdir.py
Normal file
9
testing/plugin/test_pytest_tmpdir.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from py.plugin.pytest_tmpdir import pytest_funcarg__tmpdir
|
||||
|
||||
def test_funcarg(testdir):
|
||||
from py.impl.test.funcargs import FuncargRequest
|
||||
item = testdir.getitem("def test_func(tmpdir): pass")
|
||||
p = pytest_funcarg__tmpdir(FuncargRequest(item))
|
||||
assert p.check()
|
||||
bn = p.basename.strip("0123456789-")
|
||||
assert bn.endswith("test_func")
|
||||
72
testing/plugin/test_pytest_unittest.py
Normal file
72
testing/plugin/test_pytest_unittest.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import py
|
||||
|
||||
def test_simple_unittest(testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
import unittest
|
||||
pytest_plugins = "pytest_unittest"
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def testpassing(self):
|
||||
self.assertEquals('foo', 'foo')
|
||||
def test_failing(self):
|
||||
self.assertEquals('foo', 'bar')
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath)
|
||||
assert reprec.matchreport("testpassing").passed
|
||||
assert reprec.matchreport("test_failing").failed
|
||||
|
||||
def test_isclasscheck_issue53(testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
import unittest
|
||||
class _E(object):
|
||||
def __getattr__(self, tag):
|
||||
pass
|
||||
E = _E()
|
||||
""")
|
||||
result = testdir.runpytest(testpath)
|
||||
assert result.ret == 0
|
||||
|
||||
def test_setup(testdir):
|
||||
testpath = testdir.makepyfile(test_two="""
|
||||
import unittest
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.foo = 1
|
||||
def test_setUp(self):
|
||||
self.assertEquals(1, self.foo)
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath)
|
||||
rep = reprec.matchreport("test_setUp")
|
||||
assert rep.passed
|
||||
|
||||
def test_new_instances(testdir):
|
||||
testpath = testdir.makepyfile("""
|
||||
import unittest
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def test_func1(self):
|
||||
self.x = 2
|
||||
def test_func2(self):
|
||||
assert not hasattr(self, 'x')
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath)
|
||||
reprec.assertoutcome(passed=2)
|
||||
|
||||
def test_teardown(testdir):
|
||||
testpath = testdir.makepyfile(test_three="""
|
||||
import unittest
|
||||
pytest_plugins = "pytest_unittest" # XXX
|
||||
class MyTestCase(unittest.TestCase):
|
||||
l = []
|
||||
def test_one(self):
|
||||
pass
|
||||
def tearDown(self):
|
||||
self.l.append(None)
|
||||
class Second(unittest.TestCase):
|
||||
def test_check(self):
|
||||
self.assertEquals(MyTestCase.l, [None])
|
||||
""")
|
||||
reprec = testdir.inline_run(testpath)
|
||||
passed, skipped, failed = reprec.countoutcomes()
|
||||
assert failed == 0, failed
|
||||
assert passed == 2
|
||||
assert passed + skipped + failed == 2
|
||||
|
||||
Reference in New Issue
Block a user