Skip to content

Commit 4890cd7

Browse files
committed
Add file/line for testcases
1 parent 317396b commit 4890cd7

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

xmlrunner/result.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

2+
import inspect
23
import io
34
import os
45
import sys
@@ -133,7 +134,7 @@ class _TestInfo(object):
133134
# Possible test outcomes
134135
(SUCCESS, FAILURE, ERROR, SKIP) = range(4)
135136

136-
def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=None):
137+
def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=None, filename=None, lineno=None):
137138
self.test_result = test_result
138139
self.outcome = outcome
139140
self.elapsed_time = 0
@@ -162,6 +163,9 @@ def __init__(self, test_result, test_method, outcome=SUCCESS, err=None, subTest=
162163
self.test_id = subTest.id()
163164
self.subDescription = subTest._subDescription()
164165

166+
self.filename = filename
167+
self.lineno = lineno
168+
165169
def id(self):
166170
return self.test_id
167171

@@ -211,6 +215,8 @@ def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1,
211215
self.callback = None
212216
self.elapsed_times = elapsed_times
213217
self.properties = properties # junit testsuite properties
218+
self.filename = None
219+
self.lineno = None
214220
if infoclass is None:
215221
self.infoclass = _TestInfo
216222
else:
@@ -222,6 +228,8 @@ def _prepare_callback(self, test_info, target_list, verbose_str,
222228
Appends a `infoclass` to the given target list and sets a callback
223229
method to be called by stopTest method.
224230
"""
231+
test_info.filename = self.filename
232+
test_info.lineno = self.lineno
225233
target_list.append(test_info)
226234

227235
def callback():
@@ -253,6 +261,19 @@ def startTest(self, test):
253261
self.start_time = time()
254262
TestResult.startTest(self, test)
255263

264+
try:
265+
if getattr(test, '_dt_test', None) is not None:
266+
# doctest.DocTestCase
267+
self.filename = test._dt_test.filename
268+
self.lineno = test._dt_test.lineno
269+
else:
270+
# regular unittest.TestCase?
271+
test_method = getattr(test, test._testMethodName)
272+
self.filename = inspect.getsourcefile(test_method)
273+
_, self.lineno = inspect.getsourcelines(test_method)
274+
finally:
275+
pass
276+
256277
if self.showAll:
257278
self.stream.write(' ' + self.getDescription(test))
258279
self.stream.write(" ... ")
@@ -534,6 +555,12 @@ def _report_testcase(test_result, xml_testsuite, xml_document):
534555
testcase.setAttribute('time', '%.3f' % test_result.elapsed_time)
535556
testcase.setAttribute('timestamp', test_result.timestamp)
536557

558+
if test_result.filename is not None:
559+
testcase.setAttribute('file', os.path.relpath(test_result.filename))
560+
561+
if test_result.lineno is not None:
562+
testcase.setAttribute('line', str(test_result.lineno))
563+
537564
if (test_result.outcome != test_result.SUCCESS):
538565
elem_name = ('failure', 'error', 'skipped')[test_result.outcome-1]
539566
failure = xml_document.createElement(elem_name)

0 commit comments

Comments
 (0)