Skip to content

Commit

Permalink
Adds --show-elapsed option for run_tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rconradharris committed Jun 14, 2011
1 parent 035e43f commit 00071a6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 18 deletions.
80 changes: 62 additions & 18 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
"""

import gettext
import heapq
import os
import unittest
import sys
import time

gettext.install('nova', unicode=1)

Expand Down Expand Up @@ -185,7 +187,10 @@ def write(self, text, color):

class NovaTestResult(result.TextTestResult):
def __init__(self, *args, **kw):
self.show_elapsed = kw.pop('show_elapsed')
result.TextTestResult.__init__(self, *args, **kw)
self.num_slow_tests = 5
self.slow_tests = [] # this is a fixed-sized heap
self._last_case = None
self.colorizer = None
# NOTE(vish): reset stdout for the terminal check
Expand All @@ -200,32 +205,56 @@ def __init__(self, *args, **kw):
def getDescription(self, test):
return str(test)

# NOTE(vish): copied from unittest with edit to add color
def addSuccess(self, test):
unittest.TestResult.addSuccess(self, test)
def _handleElapsedTime(self, test):
self.elapsed_time = time.time() - self.start_time
item = (self.elapsed_time, test)
# Record only the n-slowest tests using heap
if len(self.slow_tests) >= self.num_slow_tests:
heapq.heappushpop(self.slow_tests, item)
else:
heapq.heappush(self.slow_tests, item)

def _writeElapsedTime(self, test):
if self.elapsed_time >= 3.0:
color = 'red'
elif self.elapsed_time >= 1.0:
color = 'yellow'
else:
color = 'green'

self.stream.write(' ' * 10)
self.colorizer.write("%.2f" % self.elapsed_time, color)
self.stream.write(' secs')

def _writeResult(self, test, long_result, color, short_result):
if self.showAll:
self.colorizer.write("OK", 'green')
self.colorizer.write(long_result, color)
if self.show_elapsed:
self._writeElapsedTime(test)
self.stream.writeln()
elif self.dots:
self.stream.write('.')
self.stream.write(short_result)
self.stream.flush()

# NOTE(vish): copied from unittest with edit to add color
def addSuccess(self, test):
unittest.TestResult.addSuccess(self, test)
self._handleElapsedTime(test)
self._writeResult(test, 'OK', 'green', '.')

# NOTE(vish): copied from unittest with edit to add color
def addFailure(self, test, err):
unittest.TestResult.addFailure(self, test, err)
if self.showAll:
self.colorizer.write("FAIL", 'red')
self.stream.writeln()
elif self.dots:
self.stream.write('F')
self.stream.flush()
self._handleElapsedTime(test)
self._writeResult(test, 'FAIL', 'red', 'F')

# NOTE(vish): copied from nose with edit to add color
def addError(self, test, err):
"""Overrides normal addError to add support for
errorClasses. If the exception is a registered class, the
error will be added to the list for that class, not errors.
"""
self._handleElapsedTime(test)
stream = getattr(self, 'stream', None)
ec, ev, tb = err
try:
Expand All @@ -252,14 +281,11 @@ def addError(self, test, err):
self.errors.append((test, exc_info))
test.passed = False
if stream is not None:
if self.showAll:
self.colorizer.write("ERROR", 'red')
self.stream.writeln()
elif self.dots:
stream.write('E')
self._writeResult(test, 'ERROR', 'red', 'E')

def startTest(self, test):
unittest.TestResult.startTest(self, test)
self.start_time = time.time()
current_case = test.test.__class__.__name__

if self.showAll:
Expand All @@ -273,21 +299,38 @@ def startTest(self, test):


class NovaTestRunner(core.TextTestRunner):
def __init__(self, *args, **kwargs):
self.show_elapsed = kwargs.pop('show_elapsed')
core.TextTestRunner.__init__(self, *args, **kwargs)

def _makeResult(self):
return NovaTestResult(self.stream,
self.descriptions,
self.verbosity,
self.config)
self.config,
show_elapsed=self.show_elapsed)

def run(self, test):
result_ = core.TextTestRunner.run(self, test)
if self.show_elapsed:
self.stream.writeln("Slowest %i tests:" % result_.num_slow_tests)
for elapsed_time, test in reversed(sorted(result_.slow_tests)):
time_str = "%.2f secs" % elapsed_time
self.stream.writeln(" %s %s" % (time_str.ljust(10), test))
return result_


if __name__ == '__main__':
logging.setup()
# If any argument looks like a test name but doesn't have "nova.tests" in
# front of it, automatically add that so we don't have to type as much
show_elapsed = False
argv = []
for x in sys.argv:
if x.startswith('test_'):
argv.append('nova.tests.%s' % x)
elif x.startswith('--show-elapsed'):
show_elapsed = True
else:
argv.append(x)

Expand All @@ -300,5 +343,6 @@ def _makeResult(self):

runner = NovaTestRunner(stream=c.stream,
verbosity=c.verbosity,
config=c)
config=c,
show_elapsed=show_elapsed)
sys.exit(not core.run(config=c, testRunner=runner, argv=argv))
1 change: 1 addition & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function usage {
echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added."
echo " -p, --pep8 Just run pep8"
echo " -h, --help Print this usage message"
echo " --show-elapsed Print elapsed time for tests along with slowest tests"
echo ""
echo "Note: with no options specified, the script will try to run the tests in a virtual environment,"
echo " If no virtualenv is found, the script will ask if you would like to create one. If you "
Expand Down

0 comments on commit 00071a6

Please sign in to comment.