Ron*_*ury 10 python unit-testing code-coverage python-unittest
哇.我今晚发现使用该unittest模块编写的Python单元测试与模块下的覆盖率分析不trace相符.这是最简单的单元测试,在foobar.py:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
if __name__ == "__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)
如果我运行它python foobar.py,我得到这个输出:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
大.现在我也想进行覆盖测试,所以我再次运行它python -m trace --count -C . foobar.py,但现在我得到了这个:
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
不,Python,它不行 - 你没有运行我的测试!似乎在trace某种程度上运行gums up unittest的测试检测机制.这是我提出的(疯狂)解决方案:
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)
Run Code Online (Sandbox Code Playgroud)
这基本上是一种解决方法,通过伪造它的副本来提升顶级模块的抽象,不可命名的名称.然后,我可以传递该名称,unittest.main()以便回避trace对它产生的任何影响.无需向您显示输出; 它看起来就像上面的成功例子.
所以,我有两个问题:
这里发生了什么?为什么trace搞砸了unittest?
是否有一种更容易和/或更少疯狂的方法来解决这个问题?
一个更简单的解决方法是将模块的名称显式传递给unittest.main:
import unittest
class Tester(unittest.TestCase):
def test_true(self):
self.assertTrue(True)
if __name__ == "__main__":
unittest.main(module='foobar')
Run Code Online (Sandbox Code Playgroud)
traceunittest因为trace运行模块的加载方式而混淆了测试发现.trace读取模块源代码,编译它,并在__name__全局设置为的上下文中执行它'__main__'.这足以使大多数模块的行为就像它们被称为主模块一样,但实际上并没有改变__main__在Python解释器中注册的模块.当unittest要求__main__模块扫描测试用例时,它实际上trace从命令行获取调用的模块,当然这不包含单元测试.
coverage.py采用的实际替换该模块称为一种不同的方法__main__在sys.modules.
| 归档时间: |
|
| 查看次数: |
653 次 |
| 最近记录: |