Merge pull request #1791 from nicoddemus/ide-integration-1790
Internal adjustments for easier integration with IDEs
This commit is contained in:
commit
99a4a1a784
|
@ -118,13 +118,10 @@ class _NodeReporter(object):
|
||||||
|
|
||||||
def _write_captured_output(self, report):
|
def _write_captured_output(self, report):
|
||||||
for capname in ('out', 'err'):
|
for capname in ('out', 'err'):
|
||||||
allcontent = ""
|
content = getattr(report, 'capstd' + capname)
|
||||||
for name, content in report.get_sections("Captured std%s" %
|
if content:
|
||||||
capname):
|
|
||||||
allcontent += content
|
|
||||||
if allcontent:
|
|
||||||
tag = getattr(Junit, 'system-' + capname)
|
tag = getattr(Junit, 'system-' + capname)
|
||||||
self.append(tag(bin_xml_escape(allcontent)))
|
self.append(tag(bin_xml_escape(content)))
|
||||||
|
|
||||||
def append_pass(self, report):
|
def append_pass(self, report):
|
||||||
self.add_stats('passed')
|
self.add_stats('passed')
|
||||||
|
|
|
@ -357,11 +357,13 @@ class PyCollector(PyobjMixin, pytest.Collector):
|
||||||
fixtures.add_funcarg_pseudo_fixture_def(self, metafunc, fm)
|
fixtures.add_funcarg_pseudo_fixture_def(self, metafunc, fm)
|
||||||
|
|
||||||
for callspec in metafunc._calls:
|
for callspec in metafunc._calls:
|
||||||
subname = "%s[%s]" %(name, callspec.id)
|
subname = "%s[%s]" % (name, callspec.id)
|
||||||
yield Function(name=subname, parent=self,
|
yield Function(name=subname, parent=self,
|
||||||
callspec=callspec, callobj=funcobj,
|
callspec=callspec, callobj=funcobj,
|
||||||
fixtureinfo=fixtureinfo,
|
fixtureinfo=fixtureinfo,
|
||||||
keywords={callspec.id:True})
|
keywords={callspec.id:True},
|
||||||
|
originalname=name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _marked(func, mark):
|
def _marked(func, mark):
|
||||||
|
@ -1471,7 +1473,7 @@ class Function(FunctionMixin, pytest.Item, fixtures.FuncargnamesCompatAttr):
|
||||||
_genid = None
|
_genid = None
|
||||||
def __init__(self, name, parent, args=None, config=None,
|
def __init__(self, name, parent, args=None, config=None,
|
||||||
callspec=None, callobj=NOTSET, keywords=None, session=None,
|
callspec=None, callobj=NOTSET, keywords=None, session=None,
|
||||||
fixtureinfo=None):
|
fixtureinfo=None, originalname=None):
|
||||||
super(Function, self).__init__(name, parent, config=config,
|
super(Function, self).__init__(name, parent, config=config,
|
||||||
session=session)
|
session=session)
|
||||||
self._args = args
|
self._args = args
|
||||||
|
@ -1493,6 +1495,12 @@ class Function(FunctionMixin, pytest.Item, fixtures.FuncargnamesCompatAttr):
|
||||||
self.fixturenames = fixtureinfo.names_closure
|
self.fixturenames = fixtureinfo.names_closure
|
||||||
self._initrequest()
|
self._initrequest()
|
||||||
|
|
||||||
|
#: original function name, without any decorations (for example
|
||||||
|
#: parametrization adds a ``"[...]"`` suffix to function names).
|
||||||
|
#:
|
||||||
|
#: .. versionadded:: 3.0
|
||||||
|
self.originalname = originalname
|
||||||
|
|
||||||
def _initrequest(self):
|
def _initrequest(self):
|
||||||
self.funcargs = {}
|
self.funcargs = {}
|
||||||
if self._isyieldedfunction():
|
if self._isyieldedfunction():
|
||||||
|
|
|
@ -211,6 +211,36 @@ class BaseReport(object):
|
||||||
if name.startswith(prefix):
|
if name.startswith(prefix):
|
||||||
yield prefix, content
|
yield prefix, content
|
||||||
|
|
||||||
|
@property
|
||||||
|
def longreprtext(self):
|
||||||
|
"""
|
||||||
|
Read-only property that returns the full string representation
|
||||||
|
of ``longrepr``.
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
"""
|
||||||
|
tw = py.io.TerminalWriter(stringio=True)
|
||||||
|
tw.hasmarkup = False
|
||||||
|
self.toterminal(tw)
|
||||||
|
exc = tw.stringio.getvalue()
|
||||||
|
return exc.strip()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capstdout(self):
|
||||||
|
"""Return captured text from stdout, if capturing is enabled
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
"""
|
||||||
|
return ''.join(content for (prefix, content) in self.get_sections('Captured stdout'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capstderr(self):
|
||||||
|
"""Return captured text from stderr, if capturing is enabled
|
||||||
|
|
||||||
|
.. versionadded:: 3.0
|
||||||
|
"""
|
||||||
|
return ''.join(content for (prefix, content) in self.get_sections('Captured stderr'))
|
||||||
|
|
||||||
passed = property(lambda x: x.outcome == "passed")
|
passed = property(lambda x: x.outcome == "passed")
|
||||||
failed = property(lambda x: x.outcome == "failed")
|
failed = property(lambda x: x.outcome == "failed")
|
||||||
skipped = property(lambda x: x.outcome == "skipped")
|
skipped = property(lambda x: x.outcome == "skipped")
|
||||||
|
@ -276,8 +306,10 @@ class TestReport(BaseReport):
|
||||||
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
|
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
|
||||||
self.when = when
|
self.when = when
|
||||||
|
|
||||||
#: list of (secname, data) extra information which needs to
|
#: list of pairs ``(str, str)`` of extra information which needs to
|
||||||
#: marshallable
|
#: marshallable. Used by pytest to add captured text
|
||||||
|
#: from ``stdout`` and ``stderr``, but may be used by other plugins
|
||||||
|
#: to add arbitrary information to reports.
|
||||||
self.sections = list(sections)
|
self.sections = list(sections)
|
||||||
|
|
||||||
#: time it took to run just the test
|
#: time it took to run just the test
|
||||||
|
|
|
@ -632,6 +632,7 @@ Reference of objects involved in hooks
|
||||||
|
|
||||||
.. autoclass:: _pytest.runner.TestReport()
|
.. autoclass:: _pytest.runner.TestReport()
|
||||||
:members:
|
:members:
|
||||||
|
:inherited-members:
|
||||||
|
|
||||||
.. autoclass:: _pytest.vendored_packages.pluggy._CallOutcome()
|
.. autoclass:: _pytest.vendored_packages.pluggy._CallOutcome()
|
||||||
:members:
|
:members:
|
||||||
|
|
|
@ -634,6 +634,15 @@ class TestFunction:
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest()
|
||||||
result.stdout.fnmatch_lines('* 3 passed in *')
|
result.stdout.fnmatch_lines('* 3 passed in *')
|
||||||
|
|
||||||
|
def test_function_original_name(self, testdir):
|
||||||
|
items = testdir.getitems("""
|
||||||
|
import pytest
|
||||||
|
@pytest.mark.parametrize('arg', [1,2])
|
||||||
|
def test_func(arg):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
assert [x.originalname for x in items] == ['test_func', 'test_func']
|
||||||
|
|
||||||
|
|
||||||
class TestSorting:
|
class TestSorting:
|
||||||
def test_check_equality(self, testdir):
|
def test_check_equality(self, testdir):
|
||||||
|
|
|
@ -668,3 +668,68 @@ def test_store_except_info_on_eror():
|
||||||
assert sys.last_type is IndexError
|
assert sys.last_type is IndexError
|
||||||
assert sys.last_value.args[0] == 'TEST'
|
assert sys.last_value.args[0] == 'TEST'
|
||||||
assert sys.last_traceback
|
assert sys.last_traceback
|
||||||
|
|
||||||
|
|
||||||
|
class TestReportContents:
|
||||||
|
"""
|
||||||
|
Test user-level API of ``TestReport`` objects.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getrunner(self):
|
||||||
|
return lambda item: runner.runtestprotocol(item, log=False)
|
||||||
|
|
||||||
|
def test_longreprtext_pass(self, testdir):
|
||||||
|
reports = testdir.runitem("""
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
rep = reports[1]
|
||||||
|
assert rep.longreprtext == ''
|
||||||
|
|
||||||
|
def test_longreprtext_failure(self, testdir):
|
||||||
|
reports = testdir.runitem("""
|
||||||
|
def test_func():
|
||||||
|
x = 1
|
||||||
|
assert x == 4
|
||||||
|
""")
|
||||||
|
rep = reports[1]
|
||||||
|
assert 'assert 1 == 4' in rep.longreprtext
|
||||||
|
|
||||||
|
def test_captured_text(self, testdir):
|
||||||
|
reports = testdir.runitem("""
|
||||||
|
import pytest
|
||||||
|
import sys
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fix():
|
||||||
|
sys.stdout.write('setup: stdout\\n')
|
||||||
|
sys.stderr.write('setup: stderr\\n')
|
||||||
|
yield
|
||||||
|
sys.stdout.write('teardown: stdout\\n')
|
||||||
|
sys.stderr.write('teardown: stderr\\n')
|
||||||
|
assert 0
|
||||||
|
|
||||||
|
def test_func(fix):
|
||||||
|
sys.stdout.write('call: stdout\\n')
|
||||||
|
sys.stderr.write('call: stderr\\n')
|
||||||
|
assert 0
|
||||||
|
""")
|
||||||
|
setup, call, teardown = reports
|
||||||
|
assert setup.capstdout == 'setup: stdout\n'
|
||||||
|
assert call.capstdout == 'setup: stdout\ncall: stdout\n'
|
||||||
|
assert teardown.capstdout == 'setup: stdout\ncall: stdout\nteardown: stdout\n'
|
||||||
|
|
||||||
|
assert setup.capstderr == 'setup: stderr\n'
|
||||||
|
assert call.capstderr == 'setup: stderr\ncall: stderr\n'
|
||||||
|
assert teardown.capstderr == 'setup: stderr\ncall: stderr\nteardown: stderr\n'
|
||||||
|
|
||||||
|
def test_no_captured_text(self, testdir):
|
||||||
|
reports = testdir.runitem("""
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
rep = reports[1]
|
||||||
|
assert rep.capstdout == ''
|
||||||
|
assert rep.capstderr == ''
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue