@@ -1198,10 +1198,11 @@ class TestResult(unittest._TextTestResul
# unittest implementation. It is very similar to failed. It may make
# sense to map it into fail some day.
self.warned = []
self.times = []
+ self._firststarttime = None
# Data stored for the benefit of generating xunit reports.
self.successes = []
self.faildata = {}
def addFailure(self, test, reason):
@@ -1322,22 +1323,27 @@ class TestResult(unittest._TextTestResul
# os.times module computes the user time and system time spent by
# child's processes along with real elapsed time taken by a process.
# This module has one limitation. It can only work for Linux user
# and not for Windows.
test.started = os.times()
+ if self._firststarttime is None: # thread racy but irrelevant
+ self._firststarttime = test.started[4]
def stopTest(self, test, interrupted=False):
super(TestResult, self).stopTest(test)
test.stopped = os.times()
starttime = test.started
endtime = test.stopped
+ origin = self._firststarttime
self.times.append((test.name,
endtime[2] - starttime[2], # user space CPU time
endtime[3] - starttime[3], # sys space CPU time
endtime[4] - starttime[4], # real time
+ starttime[4] - origin, # start date in run context
+ endtime[4] - origin, # end date in run context
))
if interrupted:
with iolock:
self.stream.writeln('INTERRUPTED: %s (after %d seconds)' % (
@@ -1568,13 +1574,14 @@ class TextTestRunner(unittest.TextTestRu
for res, testcases in groups:
for tc, __ in testcases:
tres = {'result': res,
'time': ('%0.3f' % timesd[tc.name][2]),
'cuser': ('%0.3f' % timesd[tc.name][0]),
- 'csys': ('%0.3f' % timesd[tc.name][1])}
+ 'csys': ('%0.3f' % timesd[tc.name][1]),
+ 'start': ('%0.3f' % timesd[tc.name][3]),
+ 'end': ('%0.3f' % timesd[tc.name][4])}
outcome[tc.name] = tres
-
jsonout = json.dumps(outcome, sort_keys=True, indent=4)
fp.writelines(("testreport =", jsonout))
finally:
fp.close()
@@ -478,23 +478,29 @@ test for --json
$ cat report.json
testreport ={
"test-failure.t": [\{] (re)
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "failure", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}, ? (re)
"test-skip.t": {
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "skip", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}, ? (re)
"test-success.t": [\{] (re)
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "success", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}
} (no-eol)
Test that failed test accepted through interactive are properly reported:
@@ -517,23 +523,29 @@ Test that failed test accepted through i
$ cat report.json
testreport ={
"test-failure.t": [\{] (re)
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "success", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}, ? (re)
"test-skip.t": {
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "skip", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}, ? (re)
"test-success.t": [\{] (re)
"csys": "\s*[\d\.]{4,5}", ? (re)
"cuser": "\s*[\d\.]{4,5}", ? (re)
+ "end": "\s*[\d\.]{4,5}", ? (re)
"result": "success", ? (re)
+ "start": "\s*[\d\.]{4,5}", ? (re)
"time": "\s*[\d\.]{4,5}" (re)
}
} (no-eol)
$ mv backup test-failure.t