问题描述
哇。我今晚发现使用 unittest
模块编写的Python单元测试不能很好地与 trace
下的覆盖率分析配合使用模块。这是在 foobar.py
中最简单的单元测试:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
如果__name__ == __main__:
unittest.main()
如果我使用 python foobar.py
,我得到以下输出:
。
---------------------------------------------- ------------------------
以0.000s进行1次测试
OK
太好了。现在,我也想执行覆盖率测试,因此我再次使用 python -m trace --count -C运行它。 foobar.py
,但现在我明白了:
--------- -------------------------------------------------- -----------
在0.000s内进行了0次测试
OK
不,Python,这不行-您没有运行我的测试!似乎是在 trace
上下文中运行,以某种方式加强了 unittest
的测试检测机制。这是我想出的(疯狂的)解决方案:
import unittest
class Tester(unittest。 TestCase):
def test_true(self):
self.assertTrue(True)
class Insane(object):
pass
如果__name__ == __main__:
module = Insane()
for k,v in locals()。items():
setattr(module,k,v)
unittest.main(module)
这基本上是一种变通方法,可以简化抽象的,无法命名的伪造其副本的顶级模块的名称。然后,我可以将该名称传递给 unittest.main()
,以避开 trace
对它产生的任何影响。无需显示输出;
所以,我有两个问题:
-
这是怎么回事?为什么
trace
为unittest
搞砸了? -
有没有更容易和/或更少疯狂的方法来解决此问题?
一个更简单的解决方法是将模块的名称显式传递给 unittest.main
:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
如果__name__ == __main__:
unittest.main(module ='foobar')
trace
弄乱了 unittest
中的测试发现,因为 trace如何
加载正在运行的模块。 trace
读取模块源代码,对其进行编译,然后在将 __ name __
全局设置为<$的上下文中执行该代码。 c $ c>'__ main __'。这足以使大多数模块像它们被称为主模块一样工作,但实际上并不会更改在Python解释器中注册为 __ main __
的模块。当 unittest
要求 __ main __
模块扫描测试用例时,实际上得到了跟踪
从命令行调用的模块,该模块当然不包含单元测试。
coverage.py
采用了另一种方法来实际替换 sys.modules
中哪个模块称为 __ main __
。 / p>
Wow. I found out tonight that Python unit tests written using the unittest
module don't play well with coverage analysis under the trace
module. Here's the simplest possible unit test, in foobar.py
:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
if __name__ == "__main__":
unittest.main()
If I run this with python foobar.py
, I get this output:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Great. Now I want to perform coverage testing as well, so I run it again with python -m trace --count -C . foobar.py
, but now I get this:
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
No, Python, it's not OK - you didn't run my test! It seems as though running in the context of trace
somehow gums up unittest
's test detection mechanism. Here's the (insane) solution I came up with:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
class Insane(object):
pass
if __name__ == "__main__":
module = Insane()
for k, v in locals().items():
setattr(module, k, v)
unittest.main(module)
This is basically a workaround that reifies the abstract, unnameable name of the top-level module by faking up a copy of it. I can then pass that name to unittest.main()
so as to sidestep whatever effect trace
has on it. No need to show you the output; it looks just like the successful example above.
So, I have two questions:
What is going on here? Why does
trace
screw things up forunittest
?Is there an easier and/or less insane way to get around this problem?
A simpler workaround is to pass the name of the module explicitly to unittest.main
:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
if __name__ == "__main__":
unittest.main(module='foobar')
trace
messes up test discovery in unittest
because of how trace
loads the module it is running. trace
reads the module source code, compiles it, and executes it in a context with a __name__
global set to '__main__'
. This is enough to make most modules behave as if they were called as the main module, but doesn't actually change the module which is registered as __main__
in the Python interpreter. When unittest
asks for the __main__
module to scan for test cases, it actually gets the trace
module called from the command line, which of course doesn't contain the unit tests.
coverage.py
takes a different approach of actually replacing which module is called __main__
in sys.modules
.
这篇关于unittest.py与trace.py不能很好地配合-为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!