为什么cProfile模块不能与unittest一起使用?

Rya*_* Ye 22 python macos unit-testing cprofile

我想使用cProfile模块来分析我的单元测试.但是当我跑步的时候

python -mcProfile mytest.py
Run Code Online (Sandbox Code Playgroud)

我在'0.000秒'得到了'Ran 0测试'.这是mytest.py的源代码

import unittest

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

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

我也测试了其他更复杂的单元测试.如果我用cProfile运行它,总是得到'Ran 0 tests'.请帮忙.

更新:我的操作系统是MacOS 10.7,内置python 2.7.相同的代码在ubuntu上正常工作.

ali*_*oar 13

您必须在测试的构造函数中初始化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
Run Code Online (Sandbox Code Playgroud)

如果测试等待输入,则需要self.pr.disable()在该调用之前调用,然后重新启用它.

  • 仅供参考,Stats类可通过`from pstats import Stats`获得 (2认同)
  • 不需要`self.testtree = SplayTree (1000000)`。或者您需要为其提供导入 (2认同)

Zac*_*ung 5

我不知道为什么,但显式创建和运行测试套件似乎可行。我添加是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)
Run Code Online (Sandbox Code Playgroud)

在 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>)
Run Code Online (Sandbox Code Playgroud)


goj*_*omo 5

指定模块为我明确解决了这个问题。也就是说,更换...

    unittest.main()
Run Code Online (Sandbox Code Playgroud)

...(它试图自动发现它应该运行哪些测试)与 ...

    unittest.main(module='mytest')  # if in 'mytest.py', or as appropriate for your filename/module
Run Code Online (Sandbox Code Playgroud)

...允许适当的分析为python -m cProfile mytest.py.

  • 有效,并且是迄今为止干扰性最小、最复杂的答案。 (4认同)
  • 正如对这个想法的解释:默认情况下,unittest.main() 在“__main__”模块中查找单元 TestCase 对象。因此,当我们在 cProfile 上运行它时,模块名称是不同的,并且当我们在 unittest.main(module='mytest') 中定义显式名称时,它可以工作 (2认同)