2017-03-17 09:21:30 +08:00
|
|
|
from __future__ import absolute_import, division, print_function
|
2014-01-25 04:22:19 +08:00
|
|
|
# note: py.io capture tests where copied from
|
|
|
|
# pylib 1.4.20.dev2 (rev 13d9af95547e)
|
|
|
|
from __future__ import with_statement
|
2014-09-06 06:55:14 +08:00
|
|
|
import pickle
|
2014-01-25 04:22:19 +08:00
|
|
|
import os
|
|
|
|
import sys
|
2017-03-15 03:45:56 +08:00
|
|
|
from io import UnsupportedOperation
|
2015-11-27 22:43:01 +08:00
|
|
|
|
|
|
|
import _pytest._code
|
2014-01-25 04:22:19 +08:00
|
|
|
import py
|
|
|
|
import pytest
|
2014-01-29 18:18:15 +08:00
|
|
|
import contextlib
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
from _pytest import capture
|
2010-11-13 18:10:45 +08:00
|
|
|
from _pytest.capture import CaptureManager
|
2015-07-05 01:42:22 +08:00
|
|
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
2017-03-17 09:27:28 +08:00
|
|
|
|
2009-07-31 20:21:02 +08:00
|
|
|
|
2010-11-18 05:12:16 +08:00
|
|
|
needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')")
|
2009-10-28 04:34:11 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
if sys.version_info >= (3, 0):
|
|
|
|
def tobytes(obj):
|
|
|
|
if isinstance(obj, str):
|
|
|
|
obj = obj.encode('UTF-8')
|
|
|
|
assert isinstance(obj, bytes)
|
|
|
|
return obj
|
|
|
|
|
|
|
|
def totext(obj):
|
|
|
|
if isinstance(obj, bytes):
|
|
|
|
obj = str(obj, 'UTF-8')
|
|
|
|
assert isinstance(obj, str)
|
|
|
|
return obj
|
|
|
|
else:
|
|
|
|
def tobytes(obj):
|
|
|
|
if isinstance(obj, unicode):
|
|
|
|
obj = obj.encode('UTF-8')
|
|
|
|
assert isinstance(obj, str)
|
|
|
|
return obj
|
|
|
|
|
|
|
|
def totext(obj):
|
|
|
|
if isinstance(obj, str):
|
|
|
|
obj = unicode(obj, 'UTF-8')
|
|
|
|
assert isinstance(obj, unicode)
|
|
|
|
return obj
|
|
|
|
|
|
|
|
|
|
|
|
def oswritebytes(fd, obj):
|
|
|
|
os.write(fd, tobytes(obj))
|
|
|
|
|
|
|
|
|
2014-03-28 14:03:37 +08:00
|
|
|
def StdCaptureFD(out=True, err=True, in_=True):
|
2014-04-01 20:19:52 +08:00
|
|
|
return capture.MultiCapture(out, err, in_, Capture=capture.FDCapture)
|
2014-03-28 14:03:37 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-03-28 14:03:37 +08:00
|
|
|
def StdCapture(out=True, err=True, in_=True):
|
2014-04-01 20:19:52 +08:00
|
|
|
return capture.MultiCapture(out, err, in_, Capture=capture.SysCapture)
|
2014-03-28 14:03:37 +08:00
|
|
|
|
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestCaptureManager(object):
|
2014-04-01 20:32:12 +08:00
|
|
|
def test_getmethod_default_no_fd(self, monkeypatch):
|
|
|
|
from _pytest.capture import pytest_addoption
|
|
|
|
from _pytest.config import Parser
|
|
|
|
parser = Parser()
|
|
|
|
pytest_addoption(parser)
|
|
|
|
default = parser._groups[0].options[0].default
|
|
|
|
assert default == "fd" if hasattr(os, "dup") else "sys"
|
|
|
|
parser = Parser()
|
2009-10-28 04:34:11 +08:00
|
|
|
monkeypatch.delattr(os, 'dup', raising=False)
|
2014-04-01 20:32:12 +08:00
|
|
|
pytest_addoption(parser)
|
|
|
|
assert parser._groups[0].options[0].default == "sys"
|
2009-07-31 20:21:02 +08:00
|
|
|
|
2009-10-28 04:34:11 +08:00
|
|
|
@needsosdup
|
2014-06-16 17:27:32 +08:00
|
|
|
@pytest.mark.parametrize("method",
|
2017-07-17 07:25:07 +08:00
|
|
|
['no', 'sys', pytest.mark.skipif('not hasattr(os, "dup")', 'fd')])
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_capturing_basic_api(self, method):
|
2014-03-28 14:03:37 +08:00
|
|
|
capouter = StdCaptureFD()
|
2009-07-31 20:21:02 +08:00
|
|
|
old = sys.stdout, sys.stderr, sys.stdin
|
|
|
|
try:
|
2014-04-01 20:32:12 +08:00
|
|
|
capman = CaptureManager(method)
|
2017-09-27 06:54:26 +08:00
|
|
|
capman.start_global_capturing()
|
|
|
|
outerr = capman.suspend_global_capture()
|
2014-04-01 20:32:12 +08:00
|
|
|
assert outerr == ("", "")
|
2017-09-27 06:54:26 +08:00
|
|
|
outerr = capman.suspend_global_capture()
|
2010-05-18 01:00:39 +08:00
|
|
|
assert outerr == ("", "")
|
2017-07-21 06:14:54 +08:00
|
|
|
print("hello")
|
2017-09-27 06:54:26 +08:00
|
|
|
out, err = capman.suspend_global_capture()
|
2009-07-31 20:21:02 +08:00
|
|
|
if method == "no":
|
|
|
|
assert old == (sys.stdout, sys.stderr, sys.stdin)
|
|
|
|
else:
|
2014-04-01 20:32:12 +08:00
|
|
|
assert not out
|
2017-09-27 06:54:26 +08:00
|
|
|
capman.resume_global_capture()
|
2017-07-21 06:14:54 +08:00
|
|
|
print("hello")
|
2017-09-27 06:54:26 +08:00
|
|
|
out, err = capman.suspend_global_capture()
|
2014-04-01 20:32:12 +08:00
|
|
|
if method != "no":
|
|
|
|
assert out == "hello\n"
|
2017-09-27 06:54:26 +08:00
|
|
|
capman.stop_global_capturing()
|
2009-07-31 20:21:02 +08:00
|
|
|
finally:
|
2014-03-28 14:11:25 +08:00
|
|
|
capouter.stop_capturing()
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2009-10-28 04:34:11 +08:00
|
|
|
@needsosdup
|
2014-04-01 20:32:12 +08:00
|
|
|
def test_init_capturing(self):
|
2014-03-28 14:03:37 +08:00
|
|
|
capouter = StdCaptureFD()
|
2009-07-31 20:21:02 +08:00
|
|
|
try:
|
2014-04-01 20:32:12 +08:00
|
|
|
capman = CaptureManager("fd")
|
2017-09-27 06:54:26 +08:00
|
|
|
capman.start_global_capturing()
|
|
|
|
pytest.raises(AssertionError, "capman.start_global_capturing()")
|
|
|
|
capman.stop_global_capturing()
|
2009-07-31 20:21:02 +08:00
|
|
|
finally:
|
2014-03-28 14:11:25 +08:00
|
|
|
capouter.stop_capturing()
|
2009-07-31 20:21:02 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2013-11-21 21:40:14 +08:00
|
|
|
@pytest.mark.parametrize("method", ['fd', 'sys'])
|
2009-08-06 20:34:19 +08:00
|
|
|
def test_capturing_unicode(testdir, method):
|
2017-07-17 07:25:08 +08:00
|
|
|
if hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (2, 2):
|
2014-01-29 18:18:15 +08:00
|
|
|
pytest.xfail("does not work on pypy < 2.2")
|
2014-01-25 04:22:19 +08:00
|
|
|
if sys.version_info >= (3, 0):
|
2009-09-01 22:10:21 +08:00
|
|
|
obj = "'b\u00f6y'"
|
|
|
|
else:
|
|
|
|
obj = "u'\u00f6y'"
|
2009-08-06 20:34:19 +08:00
|
|
|
testdir.makepyfile("""
|
2010-07-04 23:06:50 +08:00
|
|
|
# coding=utf8
|
2009-08-19 22:42:29 +08:00
|
|
|
# taken from issue 227 from nosetests
|
2009-08-06 20:34:19 +08:00
|
|
|
def test_unicode():
|
|
|
|
import sys
|
2009-08-29 21:51:49 +08:00
|
|
|
print (sys.stdout)
|
2009-09-01 22:10:21 +08:00
|
|
|
print (%s)
|
|
|
|
""" % obj)
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest("--capture=%s" % method)
|
2009-08-06 20:34:19 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*1 passed*"
|
|
|
|
])
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2013-11-21 21:40:14 +08:00
|
|
|
@pytest.mark.parametrize("method", ['fd', 'sys'])
|
2009-08-19 22:42:29 +08:00
|
|
|
def test_capturing_bytes_in_utf8_encoding(testdir, method):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
def test_unicode():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ('b\\u00f6y')
|
2009-08-19 22:42:29 +08:00
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest("--capture=%s" % method)
|
2009-08-19 22:42:29 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*1 passed*"
|
|
|
|
])
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_collect_capturing(testdir):
|
|
|
|
p = testdir.makepyfile("""
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("collect %s failure" % 13)
|
2009-07-31 20:21:02 +08:00
|
|
|
import xyz42123
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2009-07-31 20:21:02 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*Captured stdout*",
|
2010-07-27 03:15:15 +08:00
|
|
|
"*collect 13 failure*",
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestPerTestCapturing(object):
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_capture_and_fixtures(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def setup_module(mod):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("setup module")
|
2009-07-31 20:21:02 +08:00
|
|
|
def setup_function(function):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("setup " + function.__name__)
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_func1():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in func1")
|
2009-07-31 20:21:02 +08:00
|
|
|
assert 0
|
|
|
|
def test_func2():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in func2")
|
2009-07-31 20:21:02 +08:00
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2009-07-31 20:21:02 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"setup module*",
|
|
|
|
"setup test_func1*",
|
|
|
|
"in func1*",
|
|
|
|
"setup test_func2*",
|
2009-11-13 04:15:59 +08:00
|
|
|
"in func2*",
|
|
|
|
])
|
2009-07-31 20:21:02 +08:00
|
|
|
|
2014-01-29 20:56:24 +08:00
|
|
|
@pytest.mark.xfail(reason="unimplemented feature")
|
2009-08-03 18:16:12 +08:00
|
|
|
def test_capture_scope_cache(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
import sys
|
|
|
|
def setup_module(func):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("module-setup")
|
2009-08-03 18:16:12 +08:00
|
|
|
def setup_function(func):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("function-setup")
|
2009-08-03 18:16:12 +08:00
|
|
|
def test_func():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in function")
|
2009-08-03 18:16:12 +08:00
|
|
|
assert 0
|
|
|
|
def teardown_function(func):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in teardown")
|
2009-08-03 18:16:12 +08:00
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2009-08-03 18:16:12 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*test_func():*",
|
2010-07-27 03:15:15 +08:00
|
|
|
"*Captured stdout during setup*",
|
|
|
|
"module-setup*",
|
|
|
|
"function-setup*",
|
2009-08-03 18:16:12 +08:00
|
|
|
"*Captured stdout*",
|
|
|
|
"in teardown*",
|
|
|
|
])
|
|
|
|
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_no_carry_over(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_func1():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in func1")
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_func2():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in func2")
|
2009-07-31 20:21:02 +08:00
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2009-07-31 20:21:02 +08:00
|
|
|
s = result.stdout.str()
|
2010-07-27 03:15:15 +08:00
|
|
|
assert "in func1" not in s
|
|
|
|
assert "in func2" in s
|
2009-07-31 20:21:02 +08:00
|
|
|
|
|
|
|
def test_teardown_capturing(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def setup_function(function):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("setup func1")
|
2009-07-31 20:21:02 +08:00
|
|
|
def teardown_function(function):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("teardown func1")
|
2009-07-31 20:21:02 +08:00
|
|
|
assert 0
|
2010-07-27 03:15:15 +08:00
|
|
|
def test_func1():
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("in func1")
|
2009-07-31 20:21:02 +08:00
|
|
|
pass
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2010-04-29 06:12:38 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
2009-07-31 20:21:02 +08:00
|
|
|
'*teardown_function*',
|
|
|
|
'*Captured stdout*',
|
|
|
|
"setup func1*",
|
|
|
|
"in func1*",
|
|
|
|
"teardown func1*",
|
2017-07-17 07:25:09 +08:00
|
|
|
# "*1 fixture failure*"
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
|
2011-12-03 05:00:21 +08:00
|
|
|
def test_teardown_capturing_final(self, testdir):
|
2009-07-31 20:21:02 +08:00
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def teardown_module(mod):
|
2009-08-29 21:51:49 +08:00
|
|
|
print ("teardown module")
|
2009-07-31 20:21:02 +08:00
|
|
|
assert 0
|
|
|
|
def test_func():
|
|
|
|
pass
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2010-04-29 06:12:38 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
2010-07-27 03:15:15 +08:00
|
|
|
"*def teardown_module(mod):*",
|
|
|
|
"*Captured stdout*",
|
|
|
|
"*teardown module*",
|
|
|
|
"*1 error*",
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
def test_capturing_outerr(self, testdir):
|
2009-07-31 20:21:02 +08:00
|
|
|
p1 = testdir.makepyfile("""
|
2010-07-27 03:15:15 +08:00
|
|
|
import sys
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_capturing():
|
2009-08-29 21:51:49 +08:00
|
|
|
print (42)
|
|
|
|
sys.stderr.write(str(23))
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_capturing_error():
|
2009-08-29 21:51:49 +08:00
|
|
|
print (1)
|
|
|
|
sys.stderr.write(str(2))
|
2009-07-31 20:21:02 +08:00
|
|
|
raise ValueError
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p1)
|
2009-07-31 20:21:02 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
2017-09-28 01:42:55 +08:00
|
|
|
"*test_capturing_outerr.py .F*",
|
2009-07-31 20:21:02 +08:00
|
|
|
"====* FAILURES *====",
|
2010-07-27 03:15:15 +08:00
|
|
|
"____*____",
|
2009-07-31 20:21:02 +08:00
|
|
|
"*test_capturing_outerr.py:8: ValueError",
|
2014-03-14 19:49:34 +08:00
|
|
|
"*--- Captured stdout *call*",
|
2009-07-31 20:21:02 +08:00
|
|
|
"1",
|
2014-03-14 19:49:34 +08:00
|
|
|
"*--- Captured stderr *call*",
|
2009-07-31 20:21:02 +08:00
|
|
|
"2",
|
|
|
|
])
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestLoggingInteraction(object):
|
2009-07-31 20:21:02 +08:00
|
|
|
def test_logging_stream_ownership(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_logging():
|
|
|
|
import logging
|
2010-11-18 05:12:16 +08:00
|
|
|
import pytest
|
2017-02-20 01:16:32 +08:00
|
|
|
stream = capture.CaptureIO()
|
2009-07-31 20:21:02 +08:00
|
|
|
logging.basicConfig(stream=stream)
|
|
|
|
stream.close() # to free memory/release resources
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p)
|
2017-07-21 06:14:54 +08:00
|
|
|
assert result.stderr.str().find("atexit") == -1
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2009-07-31 20:21:02 +08:00
|
|
|
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',)):
|
2017-07-21 06:14:54 +08:00
|
|
|
print(optargs)
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p, *optargs)
|
2009-07-31 20:21:02 +08:00
|
|
|
s = result.stdout.str()
|
|
|
|
result.stdout.fnmatch_lines([
|
2009-07-31 20:22:02 +08:00
|
|
|
"*WARN*hello3", # errors show first!
|
2010-07-27 03:15:15 +08:00
|
|
|
"*WARN*hello1",
|
|
|
|
"*WARN*hello2",
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
# 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
|
|
|
|
""")
|
2009-08-03 18:16:12 +08:00
|
|
|
for optargs in (('--capture=sys',), ('--capture=fd',)):
|
2017-07-21 06:14:54 +08:00
|
|
|
print(optargs)
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p, *optargs)
|
2009-07-31 20:21:02 +08:00
|
|
|
s = result.stdout.str()
|
|
|
|
result.stdout.fnmatch_lines([
|
2009-08-03 18:16:12 +08:00
|
|
|
"*WARN*hello3", # errors come first
|
2010-07-27 03:15:15 +08:00
|
|
|
"*WARN*hello1",
|
|
|
|
"*WARN*hello2",
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
# verify proper termination
|
|
|
|
assert "closed" not in s
|
|
|
|
|
2011-01-18 19:51:21 +08:00
|
|
|
def test_conftestlogging_is_shown(self, testdir):
|
|
|
|
testdir.makeconftest("""
|
|
|
|
import logging
|
|
|
|
logging.basicConfig()
|
|
|
|
logging.warn("hello435")
|
|
|
|
""")
|
|
|
|
# make sure that logging is still captured in tests
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess("-s", "-p", "no:capturelog")
|
2015-07-05 01:42:22 +08:00
|
|
|
assert result.ret == EXIT_NOTESTSCOLLECTED
|
2011-01-18 19:51:21 +08:00
|
|
|
result.stderr.fnmatch_lines([
|
|
|
|
"WARNING*hello435*",
|
|
|
|
])
|
|
|
|
assert 'operation on closed file' not in result.stderr.str()
|
|
|
|
|
|
|
|
def test_conftestlogging_and_test_logging(self, testdir):
|
|
|
|
testdir.makeconftest("""
|
|
|
|
import logging
|
|
|
|
logging.basicConfig()
|
|
|
|
""")
|
|
|
|
# make sure that logging is still captured in tests
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_hello():
|
|
|
|
import logging
|
|
|
|
logging.warn("hello433")
|
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p, "-p", "no:capturelog")
|
2011-01-18 19:51:21 +08:00
|
|
|
assert result.ret != 0
|
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"WARNING*hello433*",
|
|
|
|
])
|
|
|
|
assert 'something' not in result.stderr.str()
|
|
|
|
assert 'operation on closed file' not in result.stderr.str()
|
|
|
|
|
2010-12-06 23:56:12 +08:00
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestCaptureFixture(object):
|
2014-07-28 19:17:37 +08:00
|
|
|
@pytest.mark.parametrize("opt", [[], ["-s"]])
|
|
|
|
def test_std_functional(self, testdir, opt):
|
2009-07-31 20:21:02 +08:00
|
|
|
reprec = testdir.inline_runsource("""
|
|
|
|
def test_hello(capsys):
|
2009-08-29 21:51:49 +08:00
|
|
|
print (42)
|
2009-07-31 20:21:02 +08:00
|
|
|
out, err = capsys.readouterr()
|
|
|
|
assert out.startswith("42")
|
2014-07-28 19:17:37 +08:00
|
|
|
""", *opt)
|
2009-07-31 20:21:02 +08:00
|
|
|
reprec.assertoutcome(passed=1)
|
2010-07-27 03:15:15 +08:00
|
|
|
|
2012-06-04 03:01:27 +08:00
|
|
|
def test_capsyscapfd(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_one(capsys, capfd):
|
|
|
|
pass
|
|
|
|
def test_two(capfd, capsys):
|
|
|
|
pass
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2012-06-04 03:01:27 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*ERROR*setup*test_one*",
|
2017-11-15 06:08:23 +08:00
|
|
|
"E*capfd*capsys*same*time*",
|
2012-06-04 03:01:27 +08:00
|
|
|
"*ERROR*setup*test_two*",
|
2016-07-24 05:45:07 +08:00
|
|
|
"E*capsys*capfd*same*time*",
|
2012-06-04 03:01:27 +08:00
|
|
|
"*2 error*"])
|
|
|
|
|
2016-07-12 07:44:46 +08:00
|
|
|
def test_capturing_getfixturevalue(self, testdir):
|
|
|
|
"""Test that asking for "capfd" and "capsys" using request.getfixturevalue
|
|
|
|
in the same test is an error.
|
|
|
|
"""
|
|
|
|
testdir.makepyfile("""
|
|
|
|
def test_one(capsys, request):
|
|
|
|
request.getfixturevalue("capfd")
|
|
|
|
def test_two(capfd, request):
|
|
|
|
request.getfixturevalue("capsys")
|
|
|
|
""")
|
|
|
|
result = testdir.runpytest()
|
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*test_one*",
|
|
|
|
"*capsys*capfd*same*time*",
|
|
|
|
"*test_two*",
|
2017-11-15 06:08:23 +08:00
|
|
|
"*capfd*capsys*same*time*",
|
2016-07-12 07:44:46 +08:00
|
|
|
"*2 failed in*",
|
|
|
|
])
|
|
|
|
|
2017-11-15 06:08:23 +08:00
|
|
|
def test_capsyscapfdbinary(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_one(capsys, capfdbinary):
|
|
|
|
pass
|
|
|
|
""")
|
|
|
|
result = testdir.runpytest(p)
|
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*ERROR*setup*test_one*",
|
|
|
|
"E*capfdbinary*capsys*same*time*",
|
|
|
|
"*1 error*"])
|
|
|
|
|
2012-06-04 03:01:27 +08:00
|
|
|
@pytest.mark.parametrize("method", ["sys", "fd"])
|
|
|
|
def test_capture_is_represented_on_failure_issue128(self, testdir, method):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_hello(cap%s):
|
|
|
|
print ("xxx42xxx")
|
|
|
|
assert 0
|
|
|
|
""" % method)
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2012-06-04 03:01:27 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"xxx42xxx",
|
|
|
|
])
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
@needsosdup
|
|
|
|
def test_stdfd_functional(self, testdir):
|
2009-07-31 20:21:02 +08:00
|
|
|
reprec = testdir.inline_runsource("""
|
|
|
|
def test_hello(capfd):
|
|
|
|
import os
|
2009-08-29 21:51:49 +08:00
|
|
|
os.write(1, "42".encode('ascii'))
|
2009-07-31 20:21:02 +08:00
|
|
|
out, err = capfd.readouterr()
|
|
|
|
assert out.startswith("42")
|
|
|
|
capfd.close()
|
|
|
|
""")
|
|
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
2017-11-15 06:08:23 +08:00
|
|
|
@needsosdup
|
|
|
|
def test_capfdbinary(self, testdir):
|
|
|
|
reprec = testdir.inline_runsource("""
|
|
|
|
def test_hello(capfdbinary):
|
|
|
|
import os
|
|
|
|
# some likely un-decodable bytes
|
|
|
|
os.write(1, b'\\xfe\\x98\\x20')
|
|
|
|
out, err = capfdbinary.readouterr()
|
|
|
|
assert out == b'\\xfe\\x98\\x20'
|
|
|
|
assert err == b''
|
|
|
|
""")
|
|
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
2017-11-18 01:02:46 +08:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
sys.version_info < (3,),
|
|
|
|
reason='only have capsysbinary in python 3',
|
|
|
|
)
|
|
|
|
def test_capsysbinary(self, testdir):
|
|
|
|
reprec = testdir.inline_runsource("""
|
|
|
|
def test_hello(capsysbinary):
|
|
|
|
import sys
|
|
|
|
# some likely un-decodable bytes
|
|
|
|
sys.stdout.buffer.write(b'\\xfe\\x98\\x20')
|
|
|
|
out, err = capsysbinary.readouterr()
|
|
|
|
assert out == b'\\xfe\\x98\\x20'
|
|
|
|
assert err == b''
|
|
|
|
""")
|
|
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
|
|
sys.version_info >= (3,),
|
|
|
|
reason='only have capsysbinary in python 3',
|
|
|
|
)
|
|
|
|
def test_capsysbinary_forbidden_in_python2(self, testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
def test_hello(capsysbinary):
|
|
|
|
pass
|
|
|
|
""")
|
|
|
|
result = testdir.runpytest()
|
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*test_hello*",
|
|
|
|
"*capsysbinary is only supported on python 3*",
|
|
|
|
"*1 error in*",
|
|
|
|
])
|
|
|
|
|
2010-07-27 03:15:15 +08:00
|
|
|
def test_partial_setup_failure(self, testdir):
|
2009-07-31 20:21:02 +08:00
|
|
|
p = testdir.makepyfile("""
|
2010-05-18 15:54:04 +08:00
|
|
|
def test_hello(capsys, missingarg):
|
2009-07-31 20:21:02 +08:00
|
|
|
pass
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(p)
|
2010-04-29 06:12:38 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
2009-07-31 20:21:02 +08:00
|
|
|
"*test_partial_setup_failure*",
|
2009-07-31 20:22:02 +08:00
|
|
|
"*1 error*",
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
|
2009-10-28 04:34:11 +08:00
|
|
|
@needsosdup
|
2010-07-27 03:15:15 +08:00
|
|
|
def test_keyboardinterrupt_disables_capturing(self, testdir):
|
2009-07-31 20:21:02 +08:00
|
|
|
p = testdir.makepyfile("""
|
|
|
|
def test_hello(capfd):
|
|
|
|
import os
|
2009-08-29 21:51:49 +08:00
|
|
|
os.write(1, str(42).encode('ascii'))
|
2009-07-31 20:21:02 +08:00
|
|
|
raise KeyboardInterrupt()
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p)
|
2009-07-31 20:21:02 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
2010-05-25 22:52:09 +08:00
|
|
|
"*KeyboardInterrupt*"
|
2009-07-31 20:21:02 +08:00
|
|
|
])
|
|
|
|
assert result.ret == 2
|
|
|
|
|
2013-03-25 15:53:08 +08:00
|
|
|
@pytest.mark.issue14
|
|
|
|
def test_capture_and_logging(self, testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
import logging
|
|
|
|
def test_log(capsys):
|
|
|
|
logging.error('x')
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess(p)
|
2013-03-25 15:53:08 +08:00
|
|
|
assert 'closed' not in result.stderr.str()
|
|
|
|
|
2016-06-09 07:21:17 +08:00
|
|
|
@pytest.mark.parametrize('fixture', ['capsys', 'capfd'])
|
2017-09-30 04:24:31 +08:00
|
|
|
@pytest.mark.parametrize('no_capture', [True, False])
|
|
|
|
def test_disabled_capture_fixture(self, testdir, fixture, no_capture):
|
2016-06-09 07:21:17 +08:00
|
|
|
testdir.makepyfile("""
|
|
|
|
def test_disabled({fixture}):
|
|
|
|
print('captured before')
|
|
|
|
with {fixture}.disabled():
|
|
|
|
print('while capture is disabled')
|
|
|
|
print('captured after')
|
2017-09-30 04:24:31 +08:00
|
|
|
assert {fixture}.readouterr() == ('captured before\\ncaptured after\\n', '')
|
|
|
|
|
|
|
|
def test_normal():
|
|
|
|
print('test_normal executed')
|
2016-06-09 07:21:17 +08:00
|
|
|
""".format(fixture=fixture))
|
2017-09-30 04:24:31 +08:00
|
|
|
args = ('-s',) if no_capture else ()
|
|
|
|
result = testdir.runpytest_subprocess(*args)
|
2016-06-09 07:21:17 +08:00
|
|
|
result.stdout.fnmatch_lines("""
|
|
|
|
*while capture is disabled*
|
|
|
|
""")
|
|
|
|
assert 'captured before' not in result.stdout.str()
|
|
|
|
assert 'captured after' not in result.stdout.str()
|
2017-09-30 04:24:31 +08:00
|
|
|
if no_capture:
|
|
|
|
assert 'test_normal executed' in result.stdout.str()
|
|
|
|
else:
|
|
|
|
assert 'test_normal executed' not in result.stdout.str()
|
2016-06-09 07:21:17 +08:00
|
|
|
|
2017-09-26 13:34:41 +08:00
|
|
|
@pytest.mark.parametrize('fixture', ['capsys', 'capfd'])
|
|
|
|
def test_fixture_use_by_other_fixtures(self, testdir, fixture):
|
|
|
|
"""
|
|
|
|
Ensure that capsys and capfd can be used by other fixtures during setup and teardown.
|
|
|
|
"""
|
|
|
|
testdir.makepyfile("""
|
|
|
|
from __future__ import print_function
|
|
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def captured_print({fixture}):
|
|
|
|
print('stdout contents begin')
|
|
|
|
print('stderr contents begin', file=sys.stderr)
|
|
|
|
out, err = {fixture}.readouterr()
|
|
|
|
|
|
|
|
yield out, err
|
|
|
|
|
|
|
|
print('stdout contents end')
|
|
|
|
print('stderr contents end', file=sys.stderr)
|
|
|
|
out, err = {fixture}.readouterr()
|
|
|
|
assert out == 'stdout contents end\\n'
|
|
|
|
assert err == 'stderr contents end\\n'
|
|
|
|
|
|
|
|
def test_captured_print(captured_print):
|
|
|
|
out, err = captured_print
|
|
|
|
assert out == 'stdout contents begin\\n'
|
|
|
|
assert err == 'stderr contents begin\\n'
|
|
|
|
""".format(fixture=fixture))
|
|
|
|
result = testdir.runpytest_subprocess()
|
|
|
|
result.stdout.fnmatch_lines("*1 passed*")
|
|
|
|
assert 'stdout contents begin' not in result.stdout.str()
|
|
|
|
assert 'stderr contents begin' not in result.stdout.str()
|
|
|
|
|
2013-03-25 15:53:08 +08:00
|
|
|
|
2009-12-30 07:11:27 +08:00
|
|
|
def test_setup_failure_does_not_kill_capturing(testdir):
|
|
|
|
sub1 = testdir.mkpydir("sub1")
|
2015-11-27 22:43:01 +08:00
|
|
|
sub1.join("conftest.py").write(_pytest._code.Source("""
|
2009-12-30 07:11:27 +08:00
|
|
|
def pytest_runtest_setup(item):
|
|
|
|
raise ValueError(42)
|
|
|
|
"""))
|
|
|
|
sub1.join("test_mod.py").write("def test_func1(): pass")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest(testdir.tmpdir, '--traceconfig')
|
2009-12-30 07:11:27 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*ValueError(42)*",
|
|
|
|
"*1 error*"
|
|
|
|
])
|
2009-12-30 18:16:20 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2009-12-30 18:16:20 +08:00
|
|
|
def test_fdfuncarg_skips_on_no_osdup(testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import os
|
2010-04-28 21:24:38 +08:00
|
|
|
if hasattr(os, 'dup'):
|
|
|
|
del os.dup
|
2009-12-30 18:16:20 +08:00
|
|
|
def test_hello(capfd):
|
|
|
|
pass
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess("--capture=no")
|
2009-12-30 18:16:20 +08:00
|
|
|
result.stdout.fnmatch_lines([
|
|
|
|
"*1 skipped*"
|
|
|
|
])
|
2010-11-22 06:17:59 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2010-11-22 06:17:59 +08:00
|
|
|
def test_capture_conftest_runtest_setup(testdir):
|
|
|
|
testdir.makeconftest("""
|
|
|
|
def pytest_runtest_setup():
|
|
|
|
print ("hello19")
|
|
|
|
""")
|
|
|
|
testdir.makepyfile("def test_func(): pass")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest()
|
2010-11-22 06:17:59 +08:00
|
|
|
assert result.ret == 0
|
|
|
|
assert 'hello19' not in result.stdout.str()
|
2013-09-30 19:14:16 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2014-03-28 16:46:38 +08:00
|
|
|
def test_capture_badoutput_issue412(testdir):
|
2014-03-27 20:53:59 +08:00
|
|
|
testdir.makepyfile("""
|
|
|
|
import os
|
|
|
|
|
|
|
|
def test_func():
|
|
|
|
omg = bytearray([1,129,1])
|
|
|
|
os.write(1, omg)
|
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest('--cap=fd')
|
2014-03-28 16:46:38 +08:00
|
|
|
result.stdout.fnmatch_lines('''
|
|
|
|
*def test_func*
|
|
|
|
*assert 0*
|
|
|
|
*Captured*
|
|
|
|
*1 failed*
|
|
|
|
''')
|
2014-03-27 20:53:59 +08:00
|
|
|
|
|
|
|
|
2013-09-30 19:14:16 +08:00
|
|
|
def test_capture_early_option_parsing(testdir):
|
|
|
|
testdir.makeconftest("""
|
|
|
|
def pytest_runtest_setup():
|
|
|
|
print ("hello19")
|
|
|
|
""")
|
|
|
|
testdir.makepyfile("def test_func(): pass")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest("-vs")
|
2013-09-30 19:14:16 +08:00
|
|
|
assert result.ret == 0
|
|
|
|
assert 'hello19' in result.stdout.str()
|
2014-01-23 01:07:54 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2014-01-23 01:07:54 +08:00
|
|
|
def test_capture_binary_output(testdir):
|
2014-01-25 04:22:19 +08:00
|
|
|
testdir.makepyfile(r"""
|
2014-01-23 01:07:54 +08:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
def test_a():
|
|
|
|
import sys
|
|
|
|
import subprocess
|
|
|
|
subprocess.call([sys.executable, __file__])
|
|
|
|
|
|
|
|
def test_foo():
|
|
|
|
import os;os.write(1, b'\xc3')
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
test_foo()
|
|
|
|
""")
|
2015-04-28 17:54:53 +08:00
|
|
|
result = testdir.runpytest('--assert=plain')
|
|
|
|
result.assert_outcomes(passed=2)
|
2014-01-23 05:18:33 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2015-07-26 07:15:51 +08:00
|
|
|
def test_error_during_readouterr(testdir):
|
2017-02-15 23:00:18 +08:00
|
|
|
"""Make sure we suspend capturing if errors occur during readouterr"""
|
2015-07-26 07:15:51 +08:00
|
|
|
testdir.makepyfile(pytest_xyz="""
|
|
|
|
from _pytest.capture import FDCapture
|
|
|
|
def bad_snap(self):
|
|
|
|
raise Exception('boom')
|
2015-07-26 07:28:00 +08:00
|
|
|
assert FDCapture.snap
|
2015-07-26 07:15:51 +08:00
|
|
|
FDCapture.snap = bad_snap
|
|
|
|
""")
|
|
|
|
result = testdir.runpytest_subprocess(
|
|
|
|
"-p", "pytest_xyz", "--version", syspathinsert=True
|
|
|
|
)
|
|
|
|
result.stderr.fnmatch_lines([
|
|
|
|
"*in bad_snap",
|
|
|
|
" raise Exception('boom')",
|
|
|
|
"Exception: boom",
|
|
|
|
])
|
|
|
|
|
|
|
|
|
2017-02-20 01:16:32 +08:00
|
|
|
class TestCaptureIO(object):
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_text(self):
|
2017-02-20 01:16:32 +08:00
|
|
|
f = capture.CaptureIO()
|
2014-01-25 04:22:19 +08:00
|
|
|
f.write("hello")
|
|
|
|
s = f.getvalue()
|
|
|
|
assert s == "hello"
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
def test_unicode_and_str_mixture(self):
|
2017-02-20 01:16:32 +08:00
|
|
|
f = capture.CaptureIO()
|
2014-01-25 04:22:19 +08:00
|
|
|
if sys.version_info >= (3, 0):
|
|
|
|
f.write("\u00f6")
|
|
|
|
pytest.raises(TypeError, "f.write(bytes('hello', 'UTF-8'))")
|
|
|
|
else:
|
|
|
|
f.write(unicode("\u00f6", 'UTF-8'))
|
|
|
|
f.write("hello") # bytes
|
|
|
|
s = f.getvalue()
|
|
|
|
f.close()
|
|
|
|
assert isinstance(s, unicode)
|
|
|
|
|
2017-02-20 01:16:32 +08:00
|
|
|
@pytest.mark.skipif(
|
|
|
|
sys.version_info[0] == 2,
|
|
|
|
reason='python 3 only behaviour',
|
|
|
|
)
|
|
|
|
def test_write_bytes_to_buffer(self):
|
|
|
|
"""In python3, stdout / stderr are text io wrappers (exposing a buffer
|
|
|
|
property of the underlying bytestream). See issue #1407
|
|
|
|
"""
|
|
|
|
f = capture.CaptureIO()
|
|
|
|
f.buffer.write(b'foo\r\n')
|
|
|
|
assert f.getvalue() == 'foo\r\n'
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_bytes_io():
|
2014-03-28 16:46:38 +08:00
|
|
|
f = py.io.BytesIO()
|
2014-01-25 04:22:19 +08:00
|
|
|
f.write(tobytes("hello"))
|
|
|
|
pytest.raises(TypeError, "f.write(totext('hello'))")
|
|
|
|
s = f.getvalue()
|
|
|
|
assert s == tobytes("hello")
|
|
|
|
|
|
|
|
|
|
|
|
def test_dontreadfrominput():
|
|
|
|
from _pytest.capture import DontReadFromInput
|
|
|
|
f = DontReadFromInput()
|
|
|
|
assert not f.isatty()
|
|
|
|
pytest.raises(IOError, f.read)
|
|
|
|
pytest.raises(IOError, f.readlines)
|
2018-03-16 09:25:50 +08:00
|
|
|
iter_f = iter(f)
|
|
|
|
pytest.raises(IOError, next, iter_f)
|
2017-03-15 03:45:56 +08:00
|
|
|
pytest.raises(UnsupportedOperation, f.fileno)
|
2014-01-25 04:22:19 +08:00
|
|
|
f.close() # just for completeness
|
2016-08-25 06:44:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.skipif('sys.version_info < (3,)', reason='python2 has no buffer')
|
|
|
|
def test_dontreadfrominput_buffer_python3():
|
|
|
|
from _pytest.capture import DontReadFromInput
|
|
|
|
f = DontReadFromInput()
|
|
|
|
fb = f.buffer
|
|
|
|
assert not fb.isatty()
|
|
|
|
pytest.raises(IOError, fb.read)
|
|
|
|
pytest.raises(IOError, fb.readlines)
|
2018-03-16 09:25:50 +08:00
|
|
|
iter_f = iter(f)
|
|
|
|
pytest.raises(IOError, next, iter_f)
|
2016-08-25 06:44:43 +08:00
|
|
|
pytest.raises(ValueError, fb.fileno)
|
|
|
|
f.close() # just for completeness
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.skipif('sys.version_info >= (3,)', reason='python2 has no buffer')
|
|
|
|
def test_dontreadfrominput_buffer_python2():
|
|
|
|
from _pytest.capture import DontReadFromInput
|
|
|
|
f = DontReadFromInput()
|
|
|
|
with pytest.raises(AttributeError):
|
|
|
|
f.buffer
|
|
|
|
f.close() # just for completeness
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
|
2014-01-29 18:18:15 +08:00
|
|
|
@pytest.yield_fixture
|
|
|
|
def tmpfile(testdir):
|
2014-01-25 04:22:19 +08:00
|
|
|
f = testdir.makepyfile("").open('wb+')
|
2014-01-29 18:18:15 +08:00
|
|
|
yield f
|
|
|
|
if not f.closed:
|
|
|
|
f.close()
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
@needsosdup
|
|
|
|
def test_dupfile(tmpfile):
|
|
|
|
flist = []
|
|
|
|
for i in range(5):
|
2014-03-28 18:27:02 +08:00
|
|
|
nf = capture.safe_text_dupfile(tmpfile, "wb")
|
2014-01-25 04:22:19 +08:00
|
|
|
assert nf != tmpfile
|
|
|
|
assert nf.fileno() != tmpfile.fileno()
|
|
|
|
assert nf not in flist
|
2017-03-17 09:27:28 +08:00
|
|
|
print(i, end="", file=nf)
|
2014-01-25 04:22:19 +08:00
|
|
|
flist.append(nf)
|
2017-07-06 03:54:33 +08:00
|
|
|
|
|
|
|
fname_open = flist[0].name
|
|
|
|
assert fname_open == repr(flist[0].buffer)
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
for i in range(5):
|
|
|
|
f = flist[i]
|
|
|
|
f.close()
|
2017-07-06 03:54:33 +08:00
|
|
|
fname_closed = flist[0].name
|
|
|
|
assert fname_closed == repr(flist[0].buffer)
|
|
|
|
assert fname_closed != fname_open
|
2014-01-25 04:22:19 +08:00
|
|
|
tmpfile.seek(0)
|
|
|
|
s = tmpfile.read()
|
|
|
|
assert "01234" in repr(s)
|
|
|
|
tmpfile.close()
|
2017-07-06 03:54:33 +08:00
|
|
|
assert fname_closed == repr(flist[0].buffer)
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-03-28 18:27:02 +08:00
|
|
|
def test_dupfile_on_bytesio():
|
|
|
|
io = py.io.BytesIO()
|
|
|
|
f = capture.safe_text_dupfile(io, "wb")
|
|
|
|
f.write("hello")
|
|
|
|
assert io.getvalue() == b"hello"
|
2017-07-06 03:54:33 +08:00
|
|
|
assert 'BytesIO object' in f.name
|
2014-03-28 18:27:02 +08:00
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-03-28 18:27:02 +08:00
|
|
|
def test_dupfile_on_textio():
|
|
|
|
io = py.io.TextIO()
|
|
|
|
f = capture.safe_text_dupfile(io, "wb")
|
|
|
|
f.write("hello")
|
|
|
|
assert io.getvalue() == "hello"
|
2017-07-06 03:54:33 +08:00
|
|
|
assert not hasattr(f, 'name')
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
|
2014-01-29 18:18:15 +08:00
|
|
|
@contextlib.contextmanager
|
|
|
|
def lsof_check():
|
2014-01-25 04:22:19 +08:00
|
|
|
pid = os.getpid()
|
|
|
|
try:
|
|
|
|
out = py.process.cmdexec("lsof -p %d" % pid)
|
2015-07-25 04:52:56 +08:00
|
|
|
except (py.process.cmdexec.Error, UnicodeDecodeError):
|
2015-07-25 06:21:57 +08:00
|
|
|
# about UnicodeDecodeError, see note on pytester
|
2014-01-25 04:22:19 +08:00
|
|
|
pytest.skip("could not run 'lsof'")
|
2014-01-29 18:18:15 +08:00
|
|
|
yield
|
2014-01-25 04:22:19 +08:00
|
|
|
out2 = py.process.cmdexec("lsof -p %d" % pid)
|
|
|
|
len1 = len([x for x in out.split("\n") if "REG" in x])
|
|
|
|
len2 = len([x for x in out2.split("\n") if "REG" in x])
|
|
|
|
assert len2 < len1 + 3, out2
|
|
|
|
|
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestFDCapture(object):
|
2014-01-25 04:22:19 +08:00
|
|
|
pytestmark = needsosdup
|
|
|
|
|
2014-01-26 02:42:45 +08:00
|
|
|
def test_simple(self, tmpfile):
|
2014-01-25 04:22:19 +08:00
|
|
|
fd = tmpfile.fileno()
|
2014-01-26 02:42:45 +08:00
|
|
|
cap = capture.FDCapture(fd)
|
2014-01-25 04:22:19 +08:00
|
|
|
data = tobytes("hello")
|
|
|
|
os.write(fd, data)
|
2014-03-28 14:11:25 +08:00
|
|
|
s = cap.snap()
|
|
|
|
cap.done()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert not s
|
|
|
|
cap = capture.FDCapture(fd)
|
2014-01-26 02:42:45 +08:00
|
|
|
cap.start()
|
2014-01-25 04:22:19 +08:00
|
|
|
os.write(fd, data)
|
2014-03-28 14:11:25 +08:00
|
|
|
s = cap.snap()
|
|
|
|
cap.done()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert s == "hello"
|
|
|
|
|
|
|
|
def test_simple_many(self, tmpfile):
|
|
|
|
for i in range(10):
|
|
|
|
self.test_simple(tmpfile)
|
|
|
|
|
2014-01-29 18:18:15 +08:00
|
|
|
def test_simple_many_check_open_files(self, testdir):
|
|
|
|
with lsof_check():
|
|
|
|
with testdir.makepyfile("").open('wb+') as tmpfile:
|
|
|
|
self.test_simple_many(tmpfile)
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_simple_fail_second_start(self, tmpfile):
|
|
|
|
fd = tmpfile.fileno()
|
|
|
|
cap = capture.FDCapture(fd)
|
2014-03-28 14:11:25 +08:00
|
|
|
cap.done()
|
2014-01-25 04:22:19 +08:00
|
|
|
pytest.raises(ValueError, cap.start)
|
|
|
|
|
|
|
|
def test_stderr(self):
|
2014-03-28 14:03:37 +08:00
|
|
|
cap = capture.FDCapture(2)
|
2014-01-26 02:42:45 +08:00
|
|
|
cap.start()
|
2017-03-17 09:27:28 +08:00
|
|
|
print("hello", file=sys.stderr)
|
2014-03-28 14:11:25 +08:00
|
|
|
s = cap.snap()
|
|
|
|
cap.done()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert s == "hello\n"
|
|
|
|
|
|
|
|
def test_stdin(self, tmpfile):
|
2014-04-01 20:19:55 +08:00
|
|
|
cap = capture.FDCapture(0)
|
2014-01-26 02:42:45 +08:00
|
|
|
cap.start()
|
2014-01-25 04:22:19 +08:00
|
|
|
x = os.read(0, 100).strip()
|
|
|
|
cap.done()
|
2014-04-01 20:19:55 +08:00
|
|
|
assert x == tobytes('')
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_writeorg(self, tmpfile):
|
|
|
|
data1, data2 = tobytes("foo"), tobytes("bar")
|
2014-04-02 18:32:21 +08:00
|
|
|
cap = capture.FDCapture(tmpfile.fileno())
|
|
|
|
cap.start()
|
|
|
|
tmpfile.write(data1)
|
|
|
|
tmpfile.flush()
|
|
|
|
cap.writeorg(data2)
|
2014-03-28 14:11:25 +08:00
|
|
|
scap = cap.snap()
|
|
|
|
cap.done()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert scap == totext(data1)
|
2014-03-31 23:25:35 +08:00
|
|
|
with open(tmpfile.name, 'rb') as stmp_file:
|
|
|
|
stmp = stmp_file.read()
|
|
|
|
assert stmp == data2
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2014-04-01 20:19:55 +08:00
|
|
|
def test_simple_resume_suspend(self, tmpfile):
|
|
|
|
with saved_fd(1):
|
|
|
|
cap = capture.FDCapture(1)
|
|
|
|
cap.start()
|
|
|
|
data = tobytes("hello")
|
|
|
|
os.write(1, data)
|
|
|
|
sys.stdout.write("whatever")
|
|
|
|
s = cap.snap()
|
|
|
|
assert s == "hellowhatever"
|
|
|
|
cap.suspend()
|
|
|
|
os.write(1, tobytes("world"))
|
|
|
|
sys.stdout.write("qlwkej")
|
|
|
|
assert not cap.snap()
|
|
|
|
cap.resume()
|
|
|
|
os.write(1, tobytes("but now"))
|
|
|
|
sys.stdout.write(" yes\n")
|
|
|
|
s = cap.snap()
|
|
|
|
assert s == "but now yes\n"
|
|
|
|
cap.suspend()
|
|
|
|
cap.done()
|
|
|
|
pytest.raises(AttributeError, cap.suspend)
|
|
|
|
|
2014-09-22 20:56:07 +08:00
|
|
|
|
2014-04-01 20:19:55 +08:00
|
|
|
@contextlib.contextmanager
|
|
|
|
def saved_fd(fd):
|
|
|
|
new_fd = os.dup(fd)
|
|
|
|
try:
|
|
|
|
yield
|
|
|
|
finally:
|
|
|
|
os.dup2(new_fd, fd)
|
2014-09-22 20:56:07 +08:00
|
|
|
os.close(new_fd)
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2014-06-16 17:27:32 +08:00
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestStdCapture(object):
|
2014-03-28 14:55:07 +08:00
|
|
|
captureclass = staticmethod(StdCapture)
|
|
|
|
|
|
|
|
@contextlib.contextmanager
|
2014-01-25 04:22:19 +08:00
|
|
|
def getcapture(self, **kw):
|
2014-03-28 14:55:07 +08:00
|
|
|
cap = self.__class__.captureclass(**kw)
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.start_capturing()
|
2014-03-28 14:55:07 +08:00
|
|
|
try:
|
|
|
|
yield cap
|
|
|
|
finally:
|
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_capturing_done_simple(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
|
|
|
sys.stdout.write("hello")
|
|
|
|
sys.stderr.write("world")
|
|
|
|
out, err = cap.readouterr()
|
2014-03-28 14:11:25 +08:00
|
|
|
assert out == "hello"
|
|
|
|
assert err == "world"
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_capturing_reset_simple(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
|
|
|
print("hello world")
|
|
|
|
sys.stderr.write("hello error\n")
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == "hello world\n"
|
|
|
|
assert err == "hello error\n"
|
|
|
|
|
|
|
|
def test_capturing_readouterr(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
2017-07-21 06:14:54 +08:00
|
|
|
print("hello world")
|
2014-01-25 04:22:19 +08:00
|
|
|
sys.stderr.write("hello error\n")
|
|
|
|
out, err = cap.readouterr()
|
|
|
|
assert out == "hello world\n"
|
|
|
|
assert err == "hello error\n"
|
|
|
|
sys.stderr.write("error2")
|
2014-03-28 14:11:25 +08:00
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert err == "error2"
|
|
|
|
|
2017-10-29 02:53:19 +08:00
|
|
|
def test_capture_results_accessible_by_attribute(self):
|
|
|
|
with self.getcapture() as cap:
|
|
|
|
sys.stdout.write("hello")
|
|
|
|
sys.stderr.write("world")
|
|
|
|
capture_result = cap.readouterr()
|
|
|
|
assert capture_result.out == "hello"
|
|
|
|
assert capture_result.err == "world"
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_capturing_readouterr_unicode(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
2017-07-21 06:14:54 +08:00
|
|
|
print("hx\xc4\x85\xc4\x87")
|
2014-01-25 04:22:19 +08:00
|
|
|
out, err = cap.readouterr()
|
|
|
|
assert out == py.builtin._totext("hx\xc4\x85\xc4\x87\n", "utf8")
|
|
|
|
|
|
|
|
@pytest.mark.skipif('sys.version_info >= (3,)',
|
|
|
|
reason='text output different for bytes on python3')
|
|
|
|
def test_capturing_readouterr_decode_error_handling(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
|
|
|
# triggered a internal error in pytest
|
|
|
|
print('\xa6')
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == py.builtin._totext('\ufffd\n', 'unicode-escape')
|
|
|
|
|
|
|
|
def test_reset_twice_error(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
2017-07-21 06:14:54 +08:00
|
|
|
print("hello")
|
2014-03-28 14:55:07 +08:00
|
|
|
out, err = cap.readouterr()
|
2014-03-28 14:11:25 +08:00
|
|
|
pytest.raises(ValueError, cap.stop_capturing)
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == "hello\n"
|
|
|
|
assert not err
|
|
|
|
|
|
|
|
def test_capturing_modify_sysouterr_in_between(self):
|
|
|
|
oldout = sys.stdout
|
|
|
|
olderr = sys.stderr
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
|
|
|
sys.stdout.write("hello")
|
|
|
|
sys.stderr.write("world")
|
2017-02-20 01:16:32 +08:00
|
|
|
sys.stdout = capture.CaptureIO()
|
|
|
|
sys.stderr = capture.CaptureIO()
|
2017-07-21 06:14:54 +08:00
|
|
|
print("not seen")
|
2014-03-28 14:55:07 +08:00
|
|
|
sys.stderr.write("not seen\n")
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == "hello"
|
|
|
|
assert err == "world"
|
|
|
|
assert sys.stdout == oldout
|
|
|
|
assert sys.stderr == olderr
|
|
|
|
|
|
|
|
def test_capturing_error_recursive(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap1:
|
2017-07-21 06:14:54 +08:00
|
|
|
print("cap1")
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap2:
|
2017-07-21 06:14:54 +08:00
|
|
|
print("cap2")
|
2014-03-28 14:55:07 +08:00
|
|
|
out2, err2 = cap2.readouterr()
|
|
|
|
out1, err1 = cap1.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out1 == "cap1\n"
|
|
|
|
assert out2 == "cap2\n"
|
|
|
|
|
|
|
|
def test_just_out_capture(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture(out=True, err=False) as cap:
|
|
|
|
sys.stdout.write("hello")
|
|
|
|
sys.stderr.write("world")
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == "hello"
|
|
|
|
assert not err
|
|
|
|
|
|
|
|
def test_just_err_capture(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture(out=False, err=True) as cap:
|
|
|
|
sys.stdout.write("hello")
|
|
|
|
sys.stderr.write("world")
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert err == "world"
|
|
|
|
assert not out
|
|
|
|
|
|
|
|
def test_stdin_restored(self):
|
|
|
|
old = sys.stdin
|
2014-04-03 00:48:08 +08:00
|
|
|
with self.getcapture(in_=True):
|
2014-03-28 14:55:07 +08:00
|
|
|
newstdin = sys.stdin
|
2014-01-25 04:22:19 +08:00
|
|
|
assert newstdin != sys.stdin
|
|
|
|
assert sys.stdin is old
|
|
|
|
|
|
|
|
def test_stdin_nulled_by_default(self):
|
2017-07-21 06:14:54 +08:00
|
|
|
print("XXX this test may well hang instead of crashing")
|
|
|
|
print("XXX which indicates an error in the underlying capturing")
|
|
|
|
print("XXX mechanisms")
|
2014-04-03 00:48:08 +08:00
|
|
|
with self.getcapture():
|
2014-03-28 14:55:07 +08:00
|
|
|
pytest.raises(IOError, "sys.stdin.read()")
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
class TestStdCaptureFD(TestStdCapture):
|
|
|
|
pytestmark = needsosdup
|
2014-03-28 14:55:07 +08:00
|
|
|
captureclass = staticmethod(StdCaptureFD)
|
2014-01-25 04:22:19 +08:00
|
|
|
|
2014-03-28 14:11:25 +08:00
|
|
|
def test_simple_only_fd(self, testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import os
|
|
|
|
def test_x():
|
|
|
|
os.write(1, "hello\\n".encode("ascii"))
|
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess()
|
2014-03-28 14:11:25 +08:00
|
|
|
result.stdout.fnmatch_lines("""
|
|
|
|
*test_x*
|
|
|
|
*assert 0*
|
|
|
|
*Captured stdout*
|
|
|
|
""")
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
def test_intermingling(self):
|
2014-03-28 14:55:07 +08:00
|
|
|
with self.getcapture() as cap:
|
|
|
|
oswritebytes(1, "1")
|
|
|
|
sys.stdout.write(str(2))
|
|
|
|
sys.stdout.flush()
|
|
|
|
oswritebytes(1, "3")
|
|
|
|
oswritebytes(2, "a")
|
|
|
|
sys.stderr.write("b")
|
|
|
|
sys.stderr.flush()
|
|
|
|
oswritebytes(2, "c")
|
|
|
|
out, err = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
assert out == "123"
|
|
|
|
assert err == "abc"
|
|
|
|
|
|
|
|
def test_many(self, capfd):
|
2014-01-29 18:18:15 +08:00
|
|
|
with lsof_check():
|
2014-01-25 04:22:19 +08:00
|
|
|
for i in range(10):
|
2014-03-28 14:03:37 +08:00
|
|
|
cap = StdCaptureFD()
|
2014-03-28 14:11:25 +08:00
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
|
2017-02-17 02:41:51 +08:00
|
|
|
class TestStdCaptureFDinvalidFD(object):
|
2014-01-25 04:22:19 +08:00
|
|
|
pytestmark = needsosdup
|
|
|
|
|
|
|
|
def test_stdcapture_fd_invalid_fd(self, testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import os
|
2014-03-28 14:03:37 +08:00
|
|
|
from _pytest import capture
|
|
|
|
def StdCaptureFD(out=True, err=True, in_=True):
|
2014-04-01 20:19:52 +08:00
|
|
|
return capture.MultiCapture(out, err, in_,
|
2014-03-28 14:03:37 +08:00
|
|
|
Capture=capture.FDCapture)
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_stdout():
|
|
|
|
os.close(1)
|
|
|
|
cap = StdCaptureFD(out=True, err=False, in_=False)
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_stderr():
|
|
|
|
os.close(2)
|
|
|
|
cap = StdCaptureFD(out=False, err=True, in_=False)
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_stdin():
|
|
|
|
os.close(0)
|
|
|
|
cap = StdCaptureFD(out=False, err=False, in_=True)
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess("--capture=fd")
|
2014-01-25 04:22:19 +08:00
|
|
|
assert result.ret == 0
|
|
|
|
assert result.parseoutcomes()['passed'] == 3
|
|
|
|
|
|
|
|
|
|
|
|
def test_capture_not_started_but_reset():
|
2014-03-28 14:03:37 +08:00
|
|
|
capsys = StdCapture()
|
2014-03-14 19:49:36 +08:00
|
|
|
capsys.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
|
2017-07-15 22:15:26 +08:00
|
|
|
def test_using_capsys_fixture_works_with_sys_stdout_encoding(capsys):
|
|
|
|
test_text = 'test text'
|
|
|
|
|
|
|
|
print(test_text.encode(sys.stdout.encoding, 'replace'))
|
|
|
|
(out, err) = capsys.readouterr()
|
|
|
|
assert out
|
|
|
|
assert err == ''
|
|
|
|
|
|
|
|
|
2017-10-29 02:53:19 +08:00
|
|
|
def test_capsys_results_accessible_by_attribute(capsys):
|
|
|
|
sys.stdout.write("spam")
|
|
|
|
sys.stderr.write("eggs")
|
|
|
|
capture_result = capsys.readouterr()
|
|
|
|
assert capture_result.out == "spam"
|
|
|
|
assert capture_result.err == "eggs"
|
|
|
|
|
|
|
|
|
2014-01-25 04:22:19 +08:00
|
|
|
@needsosdup
|
|
|
|
@pytest.mark.parametrize('use', [True, False])
|
|
|
|
def test_fdcapture_tmpfile_remains_the_same(tmpfile, use):
|
|
|
|
if not use:
|
|
|
|
tmpfile = True
|
2014-03-28 14:03:37 +08:00
|
|
|
cap = StdCaptureFD(out=False, err=tmpfile)
|
2014-01-25 04:22:19 +08:00
|
|
|
try:
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.start_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
capfile = cap.err.tmpfile
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
finally:
|
2014-03-28 14:11:25 +08:00
|
|
|
cap.stop_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
capfile2 = cap.err.tmpfile
|
|
|
|
assert capfile2 == capfile
|
|
|
|
|
2017-07-17 07:25:09 +08:00
|
|
|
|
2014-04-01 20:19:52 +08:00
|
|
|
@needsosdup
|
|
|
|
def test_close_and_capture_again(testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import os
|
|
|
|
def test_close():
|
|
|
|
os.close(1)
|
|
|
|
def test_capture_again():
|
2014-04-01 20:32:12 +08:00
|
|
|
os.write(1, b"hello\\n")
|
2014-04-01 20:19:52 +08:00
|
|
|
assert 0
|
|
|
|
""")
|
2015-04-28 17:54:46 +08:00
|
|
|
result = testdir.runpytest_subprocess()
|
2014-04-01 20:19:52 +08:00
|
|
|
result.stdout.fnmatch_lines("""
|
|
|
|
*test_capture_again*
|
|
|
|
*assert 0*
|
|
|
|
*stdout*
|
|
|
|
*hello*
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
2014-03-28 14:03:37 +08:00
|
|
|
@pytest.mark.parametrize('method', ['SysCapture', 'FDCapture'])
|
2014-01-25 04:22:19 +08:00
|
|
|
def test_capturing_and_logging_fundamentals(testdir, method):
|
|
|
|
if method == "StdCaptureFD" and not hasattr(os, 'dup'):
|
|
|
|
pytest.skip("need os.dup")
|
|
|
|
# here we check a fundamental feature
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
import sys, os
|
|
|
|
import py, logging
|
|
|
|
from _pytest import capture
|
2014-04-01 20:19:52 +08:00
|
|
|
cap = capture.MultiCapture(out=False, in_=False,
|
2014-03-28 14:03:37 +08:00
|
|
|
Capture=capture.%s)
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.start_capturing()
|
2014-01-25 04:22:19 +08:00
|
|
|
|
|
|
|
logging.warn("hello1")
|
2014-03-14 19:49:36 +08:00
|
|
|
outerr = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
print ("suspend, captured %%s" %%(outerr,))
|
|
|
|
logging.warn("hello2")
|
|
|
|
|
2014-03-14 19:49:36 +08:00
|
|
|
cap.pop_outerr_to_orig()
|
2014-01-25 04:22:19 +08:00
|
|
|
logging.warn("hello3")
|
|
|
|
|
2014-03-14 19:49:36 +08:00
|
|
|
outerr = cap.readouterr()
|
2014-01-25 04:22:19 +08:00
|
|
|
print ("suspend2, captured %%s" %% (outerr,))
|
|
|
|
""" % (method,))
|
|
|
|
result = testdir.runpython(p)
|
2014-03-14 19:49:36 +08:00
|
|
|
result.stdout.fnmatch_lines("""
|
|
|
|
suspend, captured*hello1*
|
|
|
|
suspend2, captured*WARNING:root:hello3*
|
|
|
|
""")
|
|
|
|
result.stderr.fnmatch_lines("""
|
|
|
|
WARNING:root:hello2
|
|
|
|
""")
|
2014-01-25 04:22:19 +08:00
|
|
|
assert "atexit" not in result.stderr.str()
|
2014-04-03 02:29:10 +08:00
|
|
|
|
2014-08-07 17:05:42 +08:00
|
|
|
|
|
|
|
def test_error_attribute_issue555(testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import sys
|
|
|
|
def test_capattr():
|
|
|
|
assert sys.stdout.errors == "strict"
|
|
|
|
assert sys.stderr.errors == "strict"
|
|
|
|
""")
|
|
|
|
reprec = testdir.inline_run()
|
|
|
|
reprec.assertoutcome(passed=1)
|
2014-08-19 18:57:37 +08:00
|
|
|
|
|
|
|
|
2017-08-08 07:55:28 +08:00
|
|
|
@pytest.mark.skipif(not sys.platform.startswith('win') and sys.version_info[:2] >= (3, 6),
|
|
|
|
reason='only py3.6+ on windows')
|
|
|
|
def test_py36_windowsconsoleio_workaround_non_standard_streams():
|
|
|
|
"""
|
|
|
|
Ensure _py36_windowsconsoleio_workaround function works with objects that
|
|
|
|
do not implement the full ``io``-based stream protocol, for example execnet channels (#2666).
|
|
|
|
"""
|
|
|
|
from _pytest.capture import _py36_windowsconsoleio_workaround
|
|
|
|
|
2018-01-25 04:23:42 +08:00
|
|
|
class DummyStream(object):
|
2017-08-08 07:55:28 +08:00
|
|
|
def write(self, s):
|
|
|
|
pass
|
|
|
|
|
|
|
|
stream = DummyStream()
|
|
|
|
_py36_windowsconsoleio_workaround(stream)
|
|
|
|
|
|
|
|
|
2014-09-22 19:19:27 +08:00
|
|
|
def test_dontreadfrominput_has_encoding(testdir):
|
|
|
|
testdir.makepyfile("""
|
|
|
|
import sys
|
|
|
|
def test_capattr():
|
|
|
|
# should not raise AttributeError
|
|
|
|
assert sys.stdout.encoding
|
|
|
|
assert sys.stderr.encoding
|
|
|
|
""")
|
|
|
|
reprec = testdir.inline_run()
|
|
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
|
|
|
2018-03-14 04:41:26 +08:00
|
|
|
def test_crash_on_closing_tmpfile_py27(testdir):
|
|
|
|
testdir.makepyfile('''
|
|
|
|
from __future__ import print_function
|
|
|
|
import time
|
|
|
|
import threading
|
|
|
|
import sys
|
|
|
|
|
|
|
|
def spam():
|
|
|
|
f = sys.stderr
|
|
|
|
while True:
|
|
|
|
print('.', end='', file=f)
|
|
|
|
|
|
|
|
def test_silly():
|
|
|
|
t = threading.Thread(target=spam)
|
|
|
|
t.daemon = True
|
|
|
|
t.start()
|
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
|
|
''')
|
|
|
|
result = testdir.runpytest_subprocess()
|
|
|
|
assert result.ret == 0
|
|
|
|
assert 'IOError' not in result.stdout.str()
|
|
|
|
|
|
|
|
|
2017-11-18 01:02:46 +08:00
|
|
|
def test_pickling_and_unpickling_encoded_file():
|
2015-02-27 19:27:40 +08:00
|
|
|
# See https://bitbucket.org/pytest-dev/pytest/pull-request/194
|
2014-09-06 06:55:14 +08:00
|
|
|
# pickle.loads() raises infinite recursion if
|
|
|
|
# EncodedFile.__getattr__ is not implemented properly
|
2014-08-19 18:57:37 +08:00
|
|
|
ef = capture.EncodedFile(None, None)
|
2014-09-06 06:55:14 +08:00
|
|
|
ef_as_str = pickle.dumps(ef)
|
|
|
|
pickle.loads(ef_as_str)
|