Почему модуль cProfile не работает с unittest?

Я хотел бы использовать модуль cProfile для профилирования моих модульных тестов. Но когда я запускаю

python -mcProfile mytest.py

Я получил "Ran 0 тестов в 0.000s". Вот исходный код mytest.py

import unittest

class TestBasic(unittest.TestCase):
    def testFoo(self):
        assert True == True

if __name__ == '__main__':
    unittest.main()

Я тестировал и другие более сложные unittests. Всегда получал "Ran 0 tests", если я запускаю его с помощью cProfile. Пожалуйста, помогите.

ОБНОВЛЕНИЕ: Моя ОС - MacOS 10.7 со встроенным python 2.7. Тот же код работает правильно на ubuntu.

Ответы

Ответ 1

Вы должны инициализировать cProfiler в конструкторе теста и использовать данные профиля в деструкторе - я использую его следующим образом:

from pstats import Stats
import unittest

class TestSplayTree(unittest.TestCase):
    """a simple test"""

def setUp(self):
    """init each test"""
    self.testtree = SplayTree (1000000)
    self.pr = cProfile.Profile()
    self.pr.enable()
    print "\n<<<---"

def tearDown(self):
    """finish any test"""
    p = Stats (self.pr)
    p.strip_dirs()
    p.sort_stats ('cumtime')
    p.print_stats ()
    print "\n--->>>"
def xtest1 (self):
    pass

В случае, если тест ожидает ввода, необходимо вызвать self.pr.disable() перед этим вызовом и снова включить его.

Ответ 2

Я не уверен, почему, но явное создание и запуск набора тестов, кажется, работает. Я добавил time.sleep(2), чтобы показать что-то определенное в статистике.

import time
import unittest

class TestBasic(unittest.TestCase):
    def testFoo(self):
        time.sleep(2)
        assert True == True

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestBasic)
    unittest.TextTestRunner(verbosity=2).run(suite)

Работая в bash, сохраняя только первые 10 строк, мы видим, что {time.sleep} был самым длинным вызовом:

~ $ python -m cProfile -s tottime so.py | head -n10
testFoo (__main__.TestBasic) ... ok

----------------------------------------------------------------------
Ran 1 test in 2.003s

OK
         1084 function calls (1072 primitive calls) in 2.015 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    2.003    2.003    2.003    2.003 {time.sleep}
        1    0.002    0.002    0.003    0.003 case.py:1(<module>)
        1    0.002    0.002    0.003    0.003 collections.py:11(<module>)
        1    0.001    0.001    2.015    2.015 so.py:1(<module>)
        1    0.001    0.001    0.010    0.010 __init__.py:45(<module>)