Skip to content

Commit e9371a5

Browse files
authored
Merge pull request #3622 from RonnyPfannschmidt/builtin-serialize
move report classes to own file to prepare for serialisazion
2 parents ea379ba + 2dfb52f commit e9371a5

File tree

4 files changed

+206
-203
lines changed

4 files changed

+206
-203
lines changed

src/_pytest/reports.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import py
2+
from _pytest._code.code import TerminalRepr
3+
4+
5+
def getslaveinfoline(node):
6+
try:
7+
return node._slaveinfocache
8+
except AttributeError:
9+
d = node.slaveinfo
10+
ver = "%s.%s.%s" % d["version_info"][:3]
11+
node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
12+
d["id"],
13+
d["sysplatform"],
14+
ver,
15+
d["executable"],
16+
)
17+
return s
18+
19+
20+
class BaseReport(object):
21+
def __init__(self, **kw):
22+
self.__dict__.update(kw)
23+
24+
def toterminal(self, out):
25+
if hasattr(self, "node"):
26+
out.line(getslaveinfoline(self.node))
27+
28+
longrepr = self.longrepr
29+
if longrepr is None:
30+
return
31+
32+
if hasattr(longrepr, "toterminal"):
33+
longrepr.toterminal(out)
34+
else:
35+
try:
36+
out.line(longrepr)
37+
except UnicodeEncodeError:
38+
out.line("<unprintable longrepr>")
39+
40+
def get_sections(self, prefix):
41+
for name, content in self.sections:
42+
if name.startswith(prefix):
43+
yield prefix, content
44+
45+
@property
46+
def longreprtext(self):
47+
"""
48+
Read-only property that returns the full string representation
49+
of ``longrepr``.
50+
51+
.. versionadded:: 3.0
52+
"""
53+
tw = py.io.TerminalWriter(stringio=True)
54+
tw.hasmarkup = False
55+
self.toterminal(tw)
56+
exc = tw.stringio.getvalue()
57+
return exc.strip()
58+
59+
@property
60+
def caplog(self):
61+
"""Return captured log lines, if log capturing is enabled
62+
63+
.. versionadded:: 3.5
64+
"""
65+
return "\n".join(
66+
content for (prefix, content) in self.get_sections("Captured log")
67+
)
68+
69+
@property
70+
def capstdout(self):
71+
"""Return captured text from stdout, if capturing is enabled
72+
73+
.. versionadded:: 3.0
74+
"""
75+
return "".join(
76+
content for (prefix, content) in self.get_sections("Captured stdout")
77+
)
78+
79+
@property
80+
def capstderr(self):
81+
"""Return captured text from stderr, if capturing is enabled
82+
83+
.. versionadded:: 3.0
84+
"""
85+
return "".join(
86+
content for (prefix, content) in self.get_sections("Captured stderr")
87+
)
88+
89+
passed = property(lambda x: x.outcome == "passed")
90+
failed = property(lambda x: x.outcome == "failed")
91+
skipped = property(lambda x: x.outcome == "skipped")
92+
93+
@property
94+
def fspath(self):
95+
return self.nodeid.split("::")[0]
96+
97+
98+
class TestReport(BaseReport):
99+
""" Basic test report object (also used for setup and teardown calls if
100+
they fail).
101+
"""
102+
103+
def __init__(
104+
self,
105+
nodeid,
106+
location,
107+
keywords,
108+
outcome,
109+
longrepr,
110+
when,
111+
sections=(),
112+
duration=0,
113+
user_properties=(),
114+
**extra
115+
):
116+
#: normalized collection node id
117+
self.nodeid = nodeid
118+
119+
#: a (filesystempath, lineno, domaininfo) tuple indicating the
120+
#: actual location of a test item - it might be different from the
121+
#: collected one e.g. if a method is inherited from a different module.
122+
self.location = location
123+
124+
#: a name -> value dictionary containing all keywords and
125+
#: markers associated with a test invocation.
126+
self.keywords = keywords
127+
128+
#: test outcome, always one of "passed", "failed", "skipped".
129+
self.outcome = outcome
130+
131+
#: None or a failure representation.
132+
self.longrepr = longrepr
133+
134+
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
135+
self.when = when
136+
137+
#: user properties is a list of tuples (name, value) that holds user
138+
#: defined properties of the test
139+
self.user_properties = user_properties
140+
141+
#: list of pairs ``(str, str)`` of extra information which needs to
142+
#: marshallable. Used by pytest to add captured text
143+
#: from ``stdout`` and ``stderr``, but may be used by other plugins
144+
#: to add arbitrary information to reports.
145+
self.sections = list(sections)
146+
147+
#: time it took to run just the test
148+
self.duration = duration
149+
150+
self.__dict__.update(extra)
151+
152+
def __repr__(self):
153+
return "<TestReport %r when=%r outcome=%r>" % (
154+
self.nodeid,
155+
self.when,
156+
self.outcome,
157+
)
158+
159+
160+
class TeardownErrorReport(BaseReport):
161+
outcome = "failed"
162+
when = "teardown"
163+
164+
def __init__(self, longrepr, **extra):
165+
self.longrepr = longrepr
166+
self.sections = []
167+
self.__dict__.update(extra)
168+
169+
170+
class CollectReport(BaseReport):
171+
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
172+
self.nodeid = nodeid
173+
self.outcome = outcome
174+
self.longrepr = longrepr
175+
self.result = result or []
176+
self.sections = list(sections)
177+
self.__dict__.update(extra)
178+
179+
@property
180+
def location(self):
181+
return (self.fspath, None, self.fspath)
182+
183+
def __repr__(self):
184+
return "<CollectReport %r lenresult=%s outcome=%r>" % (
185+
self.nodeid,
186+
len(self.result),
187+
self.outcome,
188+
)
189+
190+
191+
class CollectErrorRepr(TerminalRepr):
192+
def __init__(self, msg):
193+
self.longrepr = msg
194+
195+
def toterminal(self, out):
196+
out.line(self.longrepr, red=True)

0 commit comments

Comments
 (0)