使用IDLE运行Python PyUnit单元测试
在IDLE里面,有没有办法直接运行PyUnit(unittest模块)的单元测试呢?
我问这个是因为我有一个很简单的测试模块,当我在Cygwin的命令行里用命令python mymodule.py运行时,所有测试都通过了。但是当我在IDLE里选择“运行->运行模块”时,测试虽然也通过了,但最后却出现了一个异常(SystemExit: False)。
比如,这里有一个示例测试模块,可以用来复现这个问题:
#!/usr/bin/python
import unittest
class fooTests(unittest.TestCase):
def setUp(self):
self.foo = "bar"
def testDummyTest(self):
self.assertTrue(True)
def testDummyTestTwo(self):
self.assertEquals("foo", "foo")
def tearDown(self):
self.foo = None
if __name__ == '__main__':
unittest.main()
当我在Cygwin的命令行里用python fooTests.py运行时,它会输出:
$ python fooTests.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
但是当我在IDLE里编辑fooTests.py,然后选择“运行->运行模块”时,IDLE新开的Python Shell会输出:
>>> ================================ RESTART ================================
>>>
..
----------------------------------------------------------------------
Ran 2 tests in 0.031s
OK
Traceback (most recent call last):
File "C:\Some\path\info\I\shortened\fooTests.py", line 20, in <module>
unittest.main()
File "C:\Python26\lib\unittest.py", line 817, in __init__
self.runTests()
File "C:\Python26\lib\unittest.py", line 865, in runTests
sys.exit(not result.wasSuccessful())
SystemExit: False
>>>
我到底做错了什么,导致出现这个错误信息?特别是,我该怎么做才能在IDLE里直接选择“运行->运行模块”(或者按F5)快速运行单元测试呢?
(这肯定是个简单的问题,但我快速尝试解决时却没有找到答案。)
3 个回答
类似这样的代码也应该可以用:
suite = unittest.TestLoader().loadTestsFromTestCase( fooTests )
unittest.TextTestRunner(verbosity=2).run( suite )
我在这里找到了这个信息,并且对我有效。
你也可以这样做
if __name__ == '__main__':
unittest.main(exit=False)
如果你使用的是Python 2.7或更高版本
没有人回答这个问题(我发现如果在头几分钟没有人回答,之后得到答案的可能性就会大大降低 :),所以我自己继续研究这个问题。
我不确定这是不是最好的解决办法,但我把:
if __name__ == '__main__':
unittest.main()
改成了
if __name__ == '__main__':
try: unittest.main()
except SystemExit: pass
这样似乎就解决了问题。
我猜问题出在(根据这个链接)unittest模块在结束时会调用sys.exit,这对IDLE来说是个问题,因为它希望保持Python的命令行窗口运行,而从命令行运行就没这个问题,因为命令行本身就是在运行的。
我不知道这个解决方案,即捕捉SystemExit事件并忽略它,是否会有问题,但在我检查的所有测试通过和部分测试失败的情况下,它似乎都能正常工作。
另外:可以看看这个StackOverflow的帖子:我可以用什么代码来检查Python是否在IDLE中运行?,里面提供了一个测试,看看程序是否是在IDLE中运行的。