Implement --timer-filter switch

This commit is contained in:
Stanislav Kudriashev 2015-07-19 20:57:21 +03:00
parent bf6a25e53f
commit 72a3d5af71
3 changed files with 67 additions and 21 deletions

View File

@ -12,7 +12,7 @@ Install
To install the latest release from PyPI::
pip install nose-timer
pip install nose-timer
Or to install the latest development version from Git::
@ -31,8 +31,8 @@ Usage
Run nosetests with the ``--with-timer`` flag, and you will see a list of the
tests and the time spent by each one (in seconds)::
myapp.tests.ABigTestCase.test_the_world_is_running: 56.0010s
myapp.tests.ABigTestCase.test_the_rest_of_the_galaxy_is_running: 2356.0010s
myapp.tests.ABigTestCase.test_the_world_is_running: 56.0010s
myapp.tests.ABigTestCase.test_the_rest_of_the_galaxy_is_running: 2356.0010s
How do I show only the ``n`` slowest tests?
@ -41,7 +41,7 @@ How do I show only the ``n`` slowest tests?
For example, to show only the **10** slowest tests, run nosetests with the
``--timer-top-n`` flag::
nosetests --with-timer --timer-top-n 10
nosetests --with-timer --timer-top-n 10
How do I color the output and have pretty colors?
@ -62,6 +62,22 @@ In some cases, you may want to disable colors completely. This is done by using
``--timer-no-color`` flag. This is useful when running tests in a headless console.
How do I filter results by colors?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is possible to filter results by color. To do so, you can use the
``--timer-filter`` flag::
nosetests --with-timer --timer-filer ok
nosetests --with-timer --timer-filer warning
nosetests --with-timer --timer-filer error
Or to apply several filters at once::
nosetests --with-timer --timer-filer warning,error
License
-------

View File

@ -59,6 +59,11 @@ class TimerPlugin(Plugin):
time *= 1000
return time
@staticmethod
def _parse_filter(value):
"""Parse timer filters."""
return value.split(',') if value is not None else None
def configure(self, options, config):
"""Configures the test timer plugin."""
super(TimerPlugin, self).configure(options, config)
@ -67,6 +72,7 @@ class TimerPlugin(Plugin):
self.timer_top_n = int(options.timer_top_n)
self.timer_ok = self._parse_time(options.timer_ok)
self.timer_warning = self._parse_time(options.timer_warning)
self.timer_filter = self._parse_filter(options.timer_filter)
# Windows + nosetests does not support colors (even with colorama).
if os.name == 'nt':
@ -89,12 +95,23 @@ class TimerPlugin(Plugin):
for i, (test, time_taken) in enumerate(d):
if i < self.timer_top_n or self.timer_top_n == -1:
stream.writeln(self._format_report(test, time_taken))
color = self._get_result_color(time_taken)
line = self._format_report_line(test, time_taken, color)
_filter = self._color_to_filter(color)
if (self.timer_filter is None or _filter is None or
_filter in self.timer_filter):
stream.writeln(line)
def _colored_time(self, time_taken):
"""Get formatted and colored string for a given time taken."""
if self.timer_no_color:
return "{0:0.4f}s".format(time_taken)
def _color_to_filter(self, color):
"""Get filter name by a given color."""
return {
'green': 'ok',
'yellow': 'warning',
'red': 'error',
}.get(color)
def _get_result_color(self, time_taken):
"""Get time taken result color."""
time_taken_ms = time_taken * 1000
if time_taken_ms <= self.timer_ok:
color = 'green'
@ -102,11 +119,18 @@ class TimerPlugin(Plugin):
color = 'yellow'
else:
color = 'red'
return color
def _colored_time(self, time_taken, color=None):
"""Get formatted and colored string for a given time taken."""
if self.timer_no_color:
return "{0:0.4f}s".format(time_taken)
return termcolor.colored("{0:0.4f}s".format(time_taken), color)
def _format_report(self, test, time_taken):
def _format_report_line(self, test, time_taken, color):
"""Format a single report line."""
return "{0}: {1}".format(test, self._colored_time(time_taken))
return "{0}: {1}".format(test, self._colored_time(time_taken, color))
def _register_time(self, test):
self._timed_tests[test.id()] = self._time_taken()
@ -131,7 +155,9 @@ class TimerPlugin(Plugin):
output = 'ok'
time_taken = self._timed_tests.get(test.id())
if time_taken is not None:
output += ' ({0})'.format(self._colored_time(time_taken))
color = self._get_result_color(time_taken)
output += ' ({0})'.format(self._colored_time(time_taken,
color))
result.stream.writeln(output)
elif result.dots:
result.stream.write('.')
@ -145,31 +171,30 @@ class TimerPlugin(Plugin):
"""Register commandline options."""
super(TimerPlugin, self).options(parser, env)
# timer top n
_help = ("When the timer plugin is enabled, only show the N tests "
"that consume more time. The default, -1, shows all tests.")
parser.add_option("--timer-top-n", action="store", default="-1",
dest="timer_top_n", help=_help)
_time_units_help = ("Default time unit is a second, but you can set "
"it explicitly (e.g. 1s, 500ms).")
# timer ok
_ok_help = ("Normal execution time. Such tests will be highlighted in "
"green. {units_help}".format(units_help=_time_units_help))
parser.add_option("--timer-ok", action="store", default=1,
dest="timer_ok",
help=_ok_help)
dest="timer_ok", help=_ok_help)
# time warning
_warning_help = ("Warning about execution time to highlight slow "
"tests in yellow. Tests which take more time will "
"be highlighted in red. {units_help}".format(
units_help=_time_units_help))
parser.add_option("--timer-warning", action="store", default=3,
dest="timer_warning",
help=_warning_help)
dest="timer_warning", help=_warning_help)
# timer no color
_no_color_help = "Don't colorize output (useful for non-tty output)."
# Windows + nosetests does not support colors (even with colorama).
@ -177,3 +202,8 @@ class TimerPlugin(Plugin):
parser.add_option("--timer-no-color", action="store_true",
default=False, dest="timer_no_color",
help=_no_color_help)
# timer filter
_filter_help = "Show filtered results only (ok,warning,error)"
parser.add_option("--timer-filter", action="store", default=None,
dest="timer_filter", help=_filter_help)

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, 5)
self.assertEquals(parser.add_option.call_count, 6)
def test_configure(self):
attributes = ('config', 'timer_top_n')
@ -73,7 +73,7 @@ class TestTimerPlugin(unittest.TestCase):
])
@mock.patch("nosetimer.plugin.termcolor.colored")
def test_colored_time(self, time_taken, expected, color, colored_mock):
self.plugin._colored_time(time_taken)
self.plugin._colored_time(time_taken, color)
colored_mock.assert_called_once_with(expected, color)
@mock.patch("nosetimer.plugin.termcolor.colored")