Merge pull request #76 from Carreau/json-export

Allow to export the timings as JSON.
This commit is contained in:
Stanislav 2016-07-09 09:25:12 +03:00 committed by GitHub
commit 30a99a2e0e
3 changed files with 66 additions and 17 deletions

View File

@ -22,7 +22,13 @@ Or to install the latest from source::
git clone https://github.com/mahmoudimus/nose-timer.git
cd nose-timer
python setup.py install
pip install .
You can also make a developer install if you plan on modifying the
source frequently::
pip install -e .
Usage
@ -77,6 +83,29 @@ Or to apply several filters at once::
nosetests --with-timer --timer-filter warning,error
How do I export the results ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Use the ``--timer-json-file <myfile.json>`` flag, it will save the result
in the following format::
{
'tests':
{
'<test key 1>':
{
'status': 'success'|'error'|'fail,
'time': <float in s>
},
'<test key 2>':
{
'status': 'success'|'error'|'fail,
'time': <float in s>
},
....
}
License
-------

View File

@ -1,5 +1,4 @@
import logging
import operator
import os
import re
import termcolor
@ -118,6 +117,7 @@ class TimerPlugin(Plugin):
self.timer_warning = self._parse_time(options.timer_warning)
self.timer_filter = self._parse_filter(options.timer_filter)
self.timer_no_color = True
self.json_file = options.json_file
# Windows + nosetests does not support colors (even with colorama).
if not IS_NT:
@ -140,19 +140,27 @@ class TimerPlugin(Plugin):
if self.multiprocessing_enabled:
for i in range(_results_queue.qsize()):
try:
k, v = _results_queue.get(False)
self._timed_tests[k] = v
k, v, s = _results_queue.get(False)
self._timed_tests[k] = {'time': v,
'status': s}
except Queue.Empty:
pass
d = sorted(self._timed_tests.items(),
key=operator.itemgetter(1),
key=lambda item: item[1]['time'],
reverse=True)
if self.json_file:
import json
with open(self.json_file, 'w') as f:
json.dump({'tests': dict((k, v) for k, v in d)}, f)
for i, (test, time_taken) in enumerate(d):
for i, (test, time_and_status) in enumerate(d):
time_taken = time_and_status['time']
status = time_and_status['status']
if i < self.timer_top_n or self.timer_top_n == -1:
color = self._get_result_color(time_taken)
line = self._format_report_line(test, time_taken, color)
line = self._format_report_line(test, time_taken,
color, status)
_filter = self._color_to_filter(color)
if (self.timer_filter is None or _filter is None or
_filter in self.timer_filter):
@ -184,27 +192,31 @@ class TimerPlugin(Plugin):
return "{0:0.4f}s".format(time_taken)
return termcolor.colored("{0:0.4f}s".format(time_taken), color)
def _format_report_line(self, test, time_taken, color):
def _format_report_line(self, test, time_taken, color, status):
"""Format a single report line."""
return "{0}: {1}".format(test, self._colored_time(time_taken, color))
return "[{0}]{1}: {2}".format(status, test,
self._colored_time(time_taken, color))
def _register_time(self, test):
def _register_time(self, test, status=None):
if self.multiprocessing_enabled:
_results_queue.put((test.id(), self._time_taken()))
_results_queue.put((test.id(), self._time_taken(), None))
self._timed_tests[test.id()] = self._time_taken()
self._timed_tests[test.id()] = {
'time': self._time_taken(),
'status': status
}
def addError(self, test, err, capt=None):
"""Called when a test raises an uncaught exception."""
self._register_time(test)
self._register_time(test, 'error')
def addFailure(self, test, err, capt=None, tb_info=None):
"""Called when a test fails."""
self._register_time(test)
self._register_time(test, 'fail')
def addSuccess(self, test, capt=None):
"""Called when a test passes."""
self._register_time(test)
self._register_time(test, 'success')
def prepareTestResult(self, result):
"""Called before the first test is run."""
@ -212,7 +224,7 @@ class TimerPlugin(Plugin):
"""Called when a test passes."""
if result.showAll:
output = 'ok'
time_taken = self._timed_tests.get(test.id())
time_taken = self._timed_tests.get(test.id())['time']
if time_taken is not None:
color = self._get_result_color(time_taken)
output += ' ({0})'.format(self._colored_time(time_taken,
@ -236,6 +248,14 @@ class TimerPlugin(Plugin):
parser.add_option("--timer-top-n", action="store", default="-1",
dest="timer_top_n", help=_help)
_help = ("Save the results of the timing and status of each"
"tests in said Json file")
parser.add_option("--timer-json-file", action="store",
default=None,
dest="json_file",
help=_help)
_time_units_help = ("Default time unit is a second, but you can set "
"it explicitly (e.g. 1s, 500ms).")

View File

@ -21,7 +21,7 @@ class TestTimerPlugin(unittest.TestCase):
def test_options(self):
parser = mock.MagicMock()
self.plugin.options(parser)
self.assertEquals(parser.add_option.call_count, 6)
self.assertEquals(parser.add_option.call_count, 7)
def test_configure(self):
attributes = ('config', 'timer_top_n')