This is enough to get me (relative timings), but it does not work for parallel tests, and, of course, there is an opportunity to increase the accuracy of timings. Nonetheless:
Override the default runner with settings.py :
TEST_RUNNER = 'myapp.test_runner.MyTestRunner'
From here create your own test_runner myapp myapp/test_runner.py :
from django.test.runner import DiscoverRunner class MyTestRunner(DiscoverRunner): test_runner = TimedTextTestRunner
And, in turn, override the result class so that:
from unittest.runner import TextTestRunner, TextTestResult class TimedTextTestRunner(TextTestRunner): resultclass = TimedTextTestResult
Now the result object is not only one result, but also a lot, so we need a collection of watches, with the help of the test. Then write down the start time of the test and print the time elapsed after printing the success line:
class TimedTextTestResult(TextTestResult): def __init__(self, *args, **kwargs): super(TimedTextTestResult, self).__init__(*args, **kwargs) self.clocks = dict() def startTest(self, test): self.clocks[test] = time() super(TextTestResult, self).startTest(test) if self.showAll: self.stream.write(self.getDescription(test)) self.stream.write(" ... ") self.stream.flush() def addSuccess(self, test): super(TextTestResult, self).addSuccess(test) if self.showAll: self.stream.writeln("ok-dokey (%.6fs)" % (time() - self.clocks[test])) elif self.dots: self.stream.write('.') self.stream.flush()
Which gave me test reports looking like this:
test_price_impact (api.tests.TestGroupViews) ... ok-dokey (3.123600s) test_realised_spread (api.tests.TestGroupViews) ... ok-dokey (6.894571s) test_sqrt_trade_value (api.tests.TestGroupViews) ... ok-dokey (0.147969s) test_trade_count_share (api.tests.TestGroupViews) ... ok-dokey (3.124844s) test_trade_size (api.tests.TestGroupViews) ... ok-dokey (3.134234s) test_value_share (api.tests.TestGroupViews) ... ok-dokey (2.939364s)