move test reports to own file
This commit is contained in:
parent
6b239263da
commit
cc6eb9f83c
|
@ -0,0 +1,192 @@
|
||||||
|
import py
|
||||||
|
from _pytest._code.code import TerminalRepr
|
||||||
|
|
||||||
|
|
||||||
|
def getslaveinfoline(node):
|
||||||
|
try:
|
||||||
|
return node._slaveinfocache
|
||||||
|
except AttributeError:
|
||||||
|
d = node.slaveinfo
|
||||||
|
ver = "%s.%s.%s" % d["version_info"][:3]
|
||||||
|
node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
|
||||||
|
d["id"], d["sysplatform"], ver, d["executable"]
|
||||||
|
)
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
class BaseReport(object):
|
||||||
|
|
||||||
|
def __init__(self, **kw):
|
||||||
|
self.__dict__.update(kw)
|
||||||
|
|
||||||
|
def toterminal(self, out):
|
||||||
|
if hasattr(self, "node"):
|
||||||
|
out.line(getslaveinfoline(self.node))
|
||||||
|
|
||||||
|
longrepr = self.longrepr
|
||||||
|
if longrepr is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if hasattr(longrepr, "toterminal"):
|
||||||
|
longrepr.toterminal(out)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
out.line(longrepr)
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
out.line("<unprintable longrepr>")
|
||||||
|
|
||||||
|
def get_sections(self, prefix):
|
||||||
|
for name, content in self.sections:
|
||||||
|
if name.startswith(prefix):
|
||||||
|
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 caplog(self):
|
||||||
|
"""Return captured log lines, if log capturing is enabled
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
"""
|
||||||
|
return "\n".join(
|
||||||
|
content for (prefix, content) in self.get_sections("Captured log")
|
||||||
|
)
|
||||||
|
|
||||||
|
@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")
|
||||||
|
failed = property(lambda x: x.outcome == "failed")
|
||||||
|
skipped = property(lambda x: x.outcome == "skipped")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fspath(self):
|
||||||
|
return self.nodeid.split("::")[0]
|
||||||
|
|
||||||
|
|
||||||
|
class TestReport(BaseReport):
|
||||||
|
""" Basic test report object (also used for setup and teardown calls if
|
||||||
|
they fail).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
nodeid,
|
||||||
|
location,
|
||||||
|
keywords,
|
||||||
|
outcome,
|
||||||
|
longrepr,
|
||||||
|
when,
|
||||||
|
sections=(),
|
||||||
|
duration=0,
|
||||||
|
user_properties=(),
|
||||||
|
**extra
|
||||||
|
):
|
||||||
|
#: normalized collection node id
|
||||||
|
self.nodeid = nodeid
|
||||||
|
|
||||||
|
#: a (filesystempath, lineno, domaininfo) tuple indicating the
|
||||||
|
#: actual location of a test item - it might be different from the
|
||||||
|
#: collected one e.g. if a method is inherited from a different module.
|
||||||
|
self.location = location
|
||||||
|
|
||||||
|
#: a name -> value dictionary containing all keywords and
|
||||||
|
#: markers associated with a test invocation.
|
||||||
|
self.keywords = keywords
|
||||||
|
|
||||||
|
#: test outcome, always one of "passed", "failed", "skipped".
|
||||||
|
self.outcome = outcome
|
||||||
|
|
||||||
|
#: None or a failure representation.
|
||||||
|
self.longrepr = longrepr
|
||||||
|
|
||||||
|
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
|
||||||
|
self.when = when
|
||||||
|
|
||||||
|
#: user properties is a list of tuples (name, value) that holds user
|
||||||
|
#: defined properties of the test
|
||||||
|
self.user_properties = user_properties
|
||||||
|
|
||||||
|
#: list of pairs ``(str, str)`` of extra information which needs to
|
||||||
|
#: 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)
|
||||||
|
|
||||||
|
#: time it took to run just the test
|
||||||
|
self.duration = duration
|
||||||
|
|
||||||
|
self.__dict__.update(extra)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<TestReport %r when=%r outcome=%r>" % (
|
||||||
|
self.nodeid, self.when, self.outcome
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TeardownErrorReport(BaseReport):
|
||||||
|
outcome = "failed"
|
||||||
|
when = "teardown"
|
||||||
|
|
||||||
|
def __init__(self, longrepr, **extra):
|
||||||
|
self.longrepr = longrepr
|
||||||
|
self.sections = []
|
||||||
|
self.__dict__.update(extra)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectReport(BaseReport):
|
||||||
|
|
||||||
|
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
|
||||||
|
self.nodeid = nodeid
|
||||||
|
self.outcome = outcome
|
||||||
|
self.longrepr = longrepr
|
||||||
|
self.result = result or []
|
||||||
|
self.sections = list(sections)
|
||||||
|
self.__dict__.update(extra)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def location(self):
|
||||||
|
return (self.fspath, None, self.fspath)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<CollectReport %r lenresult=%s outcome=%r>" % (
|
||||||
|
self.nodeid, len(self.result), self.outcome
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CollectErrorRepr(TerminalRepr):
|
||||||
|
|
||||||
|
def __init__(self, msg):
|
||||||
|
self.longrepr = msg
|
||||||
|
|
||||||
|
def toterminal(self, out):
|
||||||
|
out.line(self.longrepr, red=True)
|
|
@ -7,9 +7,11 @@ import sys
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
import py
|
import py
|
||||||
from _pytest._code.code import TerminalRepr, ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest.outcomes import skip, Skipped, TEST_OUTCOME
|
from _pytest.outcomes import skip, Skipped, TEST_OUTCOME
|
||||||
|
|
||||||
|
from .reports import TestReport, CollectReport, CollectErrorRepr
|
||||||
|
|
||||||
#
|
#
|
||||||
# pytest plugin hooks
|
# pytest plugin hooks
|
||||||
|
|
||||||
|
@ -215,98 +217,45 @@ class CallInfo(object):
|
||||||
return "<CallInfo when=%r %s>" % (self.when, status)
|
return "<CallInfo when=%r %s>" % (self.when, status)
|
||||||
|
|
||||||
|
|
||||||
def getslaveinfoline(node):
|
def pytest_runtest_makereport(item, call):
|
||||||
try:
|
when = call.when
|
||||||
return node._slaveinfocache
|
duration = call.stop - call.start
|
||||||
except AttributeError:
|
keywords = {x: 1 for x in item.keywords}
|
||||||
d = node.slaveinfo
|
excinfo = call.excinfo
|
||||||
ver = "%s.%s.%s" % d["version_info"][:3]
|
sections = []
|
||||||
node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
|
if not call.excinfo:
|
||||||
d["id"],
|
outcome = "passed"
|
||||||
d["sysplatform"],
|
longrepr = None
|
||||||
ver,
|
|
||||||
d["executable"],
|
|
||||||
)
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
class BaseReport(object):
|
|
||||||
def __init__(self, **kw):
|
|
||||||
self.__dict__.update(kw)
|
|
||||||
|
|
||||||
def toterminal(self, out):
|
|
||||||
if hasattr(self, "node"):
|
|
||||||
out.line(getslaveinfoline(self.node))
|
|
||||||
|
|
||||||
longrepr = self.longrepr
|
|
||||||
if longrepr is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
if hasattr(longrepr, "toterminal"):
|
|
||||||
longrepr.toterminal(out)
|
|
||||||
else:
|
else:
|
||||||
try:
|
if not isinstance(excinfo, ExceptionInfo):
|
||||||
out.line(longrepr)
|
outcome = "failed"
|
||||||
except UnicodeEncodeError:
|
longrepr = excinfo
|
||||||
out.line("<unprintable longrepr>")
|
elif excinfo.errisinstance(skip.Exception):
|
||||||
|
outcome = "skipped"
|
||||||
def get_sections(self, prefix):
|
r = excinfo._getreprcrash()
|
||||||
for name, content in self.sections:
|
longrepr = (str(r.path), r.lineno, r.message)
|
||||||
if name.startswith(prefix):
|
else:
|
||||||
yield prefix, content
|
outcome = "failed"
|
||||||
|
if call.when == "call":
|
||||||
@property
|
longrepr = item.repr_failure(excinfo)
|
||||||
def longreprtext(self):
|
else: # exception in setup or teardown
|
||||||
"""
|
longrepr = item._repr_failure_py(
|
||||||
Read-only property that returns the full string representation
|
excinfo, style=item.config.option.tbstyle
|
||||||
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 caplog(self):
|
|
||||||
"""Return captured log lines, if log capturing is enabled
|
|
||||||
|
|
||||||
.. versionadded:: 3.5
|
|
||||||
"""
|
|
||||||
return "\n".join(
|
|
||||||
content for (prefix, content) in self.get_sections("Captured log")
|
|
||||||
)
|
)
|
||||||
|
for rwhen, key, content in item._report_sections:
|
||||||
@property
|
sections.append(("Captured %s %s" % (key, rwhen), content))
|
||||||
def capstdout(self):
|
return TestReport(
|
||||||
"""Return captured text from stdout, if capturing is enabled
|
item.nodeid,
|
||||||
|
item.location,
|
||||||
.. versionadded:: 3.0
|
keywords,
|
||||||
"""
|
outcome,
|
||||||
return "".join(
|
longrepr,
|
||||||
content for (prefix, content) in self.get_sections("Captured stdout")
|
when,
|
||||||
|
sections,
|
||||||
|
duration,
|
||||||
|
user_properties=item.user_properties,
|
||||||
)
|
)
|
||||||
|
|
||||||
@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")
|
|
||||||
failed = property(lambda x: x.outcome == "failed")
|
|
||||||
skipped = property(lambda x: x.outcome == "skipped")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def fspath(self):
|
|
||||||
return self.nodeid.split("::")[0]
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_runtest_makereport(item, call):
|
def pytest_runtest_makereport(item, call):
|
||||||
when = call.when
|
when = call.when
|
||||||
|
@ -348,78 +297,6 @@ def pytest_runtest_makereport(item, call):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestReport(BaseReport):
|
|
||||||
""" Basic test report object (also used for setup and teardown calls if
|
|
||||||
they fail).
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
nodeid,
|
|
||||||
location,
|
|
||||||
keywords,
|
|
||||||
outcome,
|
|
||||||
longrepr,
|
|
||||||
when,
|
|
||||||
sections=(),
|
|
||||||
duration=0,
|
|
||||||
user_properties=(),
|
|
||||||
**extra
|
|
||||||
):
|
|
||||||
#: normalized collection node id
|
|
||||||
self.nodeid = nodeid
|
|
||||||
|
|
||||||
#: a (filesystempath, lineno, domaininfo) tuple indicating the
|
|
||||||
#: actual location of a test item - it might be different from the
|
|
||||||
#: collected one e.g. if a method is inherited from a different module.
|
|
||||||
self.location = location
|
|
||||||
|
|
||||||
#: a name -> value dictionary containing all keywords and
|
|
||||||
#: markers associated with a test invocation.
|
|
||||||
self.keywords = keywords
|
|
||||||
|
|
||||||
#: test outcome, always one of "passed", "failed", "skipped".
|
|
||||||
self.outcome = outcome
|
|
||||||
|
|
||||||
#: None or a failure representation.
|
|
||||||
self.longrepr = longrepr
|
|
||||||
|
|
||||||
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
|
|
||||||
self.when = when
|
|
||||||
|
|
||||||
#: user properties is a list of tuples (name, value) that holds user
|
|
||||||
#: defined properties of the test
|
|
||||||
self.user_properties = user_properties
|
|
||||||
|
|
||||||
#: list of pairs ``(str, str)`` of extra information which needs to
|
|
||||||
#: 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)
|
|
||||||
|
|
||||||
#: time it took to run just the test
|
|
||||||
self.duration = duration
|
|
||||||
|
|
||||||
self.__dict__.update(extra)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<TestReport %r when=%r outcome=%r>" % (
|
|
||||||
self.nodeid,
|
|
||||||
self.when,
|
|
||||||
self.outcome,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TeardownErrorReport(BaseReport):
|
|
||||||
outcome = "failed"
|
|
||||||
when = "teardown"
|
|
||||||
|
|
||||||
def __init__(self, longrepr, **extra):
|
|
||||||
self.longrepr = longrepr
|
|
||||||
self.sections = []
|
|
||||||
self.__dict__.update(extra)
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_make_collect_report(collector):
|
def pytest_make_collect_report(collector):
|
||||||
call = CallInfo(lambda: list(collector.collect()), "collect")
|
call = CallInfo(lambda: list(collector.collect()), "collect")
|
||||||
longrepr = None
|
longrepr = None
|
||||||
|
@ -446,35 +323,6 @@ def pytest_make_collect_report(collector):
|
||||||
return rep
|
return rep
|
||||||
|
|
||||||
|
|
||||||
class CollectReport(BaseReport):
|
|
||||||
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
|
|
||||||
self.nodeid = nodeid
|
|
||||||
self.outcome = outcome
|
|
||||||
self.longrepr = longrepr
|
|
||||||
self.result = result or []
|
|
||||||
self.sections = list(sections)
|
|
||||||
self.__dict__.update(extra)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def location(self):
|
|
||||||
return (self.fspath, None, self.fspath)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<CollectReport %r lenresult=%s outcome=%r>" % (
|
|
||||||
self.nodeid,
|
|
||||||
len(self.result),
|
|
||||||
self.outcome,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CollectErrorRepr(TerminalRepr):
|
|
||||||
def __init__(self, msg):
|
|
||||||
self.longrepr = msg
|
|
||||||
|
|
||||||
def toterminal(self, out):
|
|
||||||
out.line(self.longrepr, red=True)
|
|
||||||
|
|
||||||
|
|
||||||
class SetupState(object):
|
class SetupState(object):
|
||||||
""" shared state for setting up/tearing down test items or collectors. """
|
""" shared state for setting up/tearing down test items or collectors. """
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ import os
|
||||||
from _pytest.junitxml import LogXML
|
from _pytest.junitxml import LogXML
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from _pytest.reports import BaseReport
|
||||||
|
|
||||||
|
|
||||||
def runandparse(testdir, *args):
|
def runandparse(testdir, *args):
|
||||||
resultpath = testdir.tmpdir.join("junit.xml")
|
resultpath = testdir.tmpdir.join("junit.xml")
|
||||||
|
@ -940,7 +942,6 @@ def test_unicode_issue368(testdir):
|
||||||
path = testdir.tmpdir.join("test.xml")
|
path = testdir.tmpdir.join("test.xml")
|
||||||
log = LogXML(str(path), None)
|
log = LogXML(str(path), None)
|
||||||
ustr = py.builtin._totext("ВНИ!", "utf-8")
|
ustr = py.builtin._totext("ВНИ!", "utf-8")
|
||||||
from _pytest.runner import BaseReport
|
|
||||||
|
|
||||||
class Report(BaseReport):
|
class Report(BaseReport):
|
||||||
longrepr = ustr
|
longrepr = ustr
|
||||||
|
@ -1137,7 +1138,6 @@ def test_fancy_items_regression(testdir):
|
||||||
def test_global_properties(testdir):
|
def test_global_properties(testdir):
|
||||||
path = testdir.tmpdir.join("test_global_properties.xml")
|
path = testdir.tmpdir.join("test_global_properties.xml")
|
||||||
log = LogXML(str(path), None)
|
log = LogXML(str(path), None)
|
||||||
from _pytest.runner import BaseReport
|
|
||||||
|
|
||||||
class Report(BaseReport):
|
class Report(BaseReport):
|
||||||
sections = []
|
sections = []
|
||||||
|
@ -1173,7 +1173,6 @@ def test_url_property(testdir):
|
||||||
test_url = "http://www.github.com/pytest-dev"
|
test_url = "http://www.github.com/pytest-dev"
|
||||||
path = testdir.tmpdir.join("test_url_property.xml")
|
path = testdir.tmpdir.join("test_url_property.xml")
|
||||||
log = LogXML(str(path), None)
|
log = LogXML(str(path), None)
|
||||||
from _pytest.runner import BaseReport
|
|
||||||
|
|
||||||
class Report(BaseReport):
|
class Report(BaseReport):
|
||||||
longrepr = "FooBarBaz"
|
longrepr = "FooBarBaz"
|
||||||
|
|
|
@ -8,7 +8,7 @@ import py
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
from _pytest import runner, main, outcomes
|
from _pytest import runner, main, outcomes, reports
|
||||||
|
|
||||||
|
|
||||||
class TestSetupState(object):
|
class TestSetupState(object):
|
||||||
|
@ -459,10 +459,10 @@ class TestSessionReports(object):
|
||||||
|
|
||||||
|
|
||||||
reporttypes = [
|
reporttypes = [
|
||||||
runner.BaseReport,
|
reports.BaseReport,
|
||||||
runner.TestReport,
|
reports.TestReport,
|
||||||
runner.TeardownErrorReport,
|
reports.TeardownErrorReport,
|
||||||
runner.CollectReport,
|
reports.CollectReport,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue