Unittest presents only total time spent on running all tests but does not present time spent on each test separately.
How to add timing of each test when using unittest?
PyCharm CE (free) provides a clean view of unittest
durations. It also helpfully aggregates by directory structure and file and allows you to sort by duration:
And as @horejsek mentioned, there's an issue for unittest
to add duration measurement with an open PR: https://github.com/python/cpython/pull/12271.
You can use pytest with --durations=0
and it will give you execution time for each test
Solution with command-line only:
1/ install nose
(popular alternative test-runner) and extension pinnochio
$ pip install nose pinnochio
2/ run tests with time recording (times are saved in file .nose-stopwatch-times
)
$ nosetests --with-stopwatch
3/ display tests names sorted by decreasing time:
$ python -c "import pickle,operator,signal; signal.signal(signal.SIGPIPE, signal.SIG_DFL); print '\n'.join(['%.03fs: %s'%(v[1],v[0]) for v in sorted(pickle.load(open('.nose-stopwatch-times','r')).items(), key=operator.itemgetter(1), reverse=True)])" | less
You can use django-slowtests, which provides output like this:
$ python manage.py test
Creating test database for alias 'default'...
..........
----------------------------------------------------------------------
Ran 10 tests in 0.413s
OK
Destroying test database for alias 'default'...
Ten slowest tests:
0.3597s test_detail_view_with_a_future_poll (polls.tests.PollIndexDetailTests)
0.0284s test_detail_view_with_a_past_poll (polls.tests.PollIndexDetailTests)
0.0068s test_index_view_with_a_future_poll (polls.tests.PollViewTests)
0.0047s test_index_view_with_a_past_poll (polls.tests.PollViewTests)
0.0045s test_index_view_with_two_past_polls (polls.tests.PollViewTests)
0.0041s test_index_view_with_future_poll_and_past_poll (polls.tests.PollViewTests)
0.0036s test_index_view_with_no_polls (polls.tests.PollViewTests)
0.0003s test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
0.0002s test_was_published_recently_with_recent_poll (polls.tests.PollMethodTests)
0.0002s test_was_published_recently_with_old_poll (polls.tests.PollMethodTests)
If you look at django_slowtests/test_runner.py you could also adapt the technique yourself.
I suppose, that it's not possible for now: http://bugs.python.org/issue4080.
But you can do something like this:
import unittest
import time
class SomeTest(unittest.TestCase):
def setUp(self):
self.startTime = time.time()
def tearDown(self):
t = time.time() - self.startTime
print('%s: %.3f' % (self.id(), t))
def testOne(self):
time.sleep(1)
self.assertEqual(int('42'), 42)
def testTwo(self):
time.sleep(2)
self.assertEqual(str(42), '42')
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SomeTest)
unittest.TextTestRunner(verbosity=0).run(suite)
Result:
__main__.SomeTest.testOne: 1.001
__main__.SomeTest.testTwo: 2.002
----------------------------------------------------------------------
Ran 2 tests in 3.003s
OK
Nose tests with the pinnochio extension has a stopwatch option which will give you this, if nose is an option for you.
It also has a ton of other useful features and plugins to make using unittest nicer.