Skip to content

Commit cc6eb9f

Browse files
move test reports to own file
1 parent 6b23926 commit cc6eb9f

File tree

4 files changed

+236
-197
lines changed

4 files changed

+236
-197
lines changed

src/_pytest/reports.py

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

0 commit comments

Comments
 (0)