Using IDLE to run Python PyUnit unit tests
Is there a way, within IDLE, to run the PyUnit (unittest module) unit tests directly?
I ask because I have a short test module and when I run it with python mymodule.py from the Cygwin s开发者_运维技巧hell I get all tests passed, but when I use Run->Run Module from IDLE the tests pass but then I get an exception (SystemExit: False).
For example, here is a sample test module to reproduce this:
#!/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()
When I run this from the Cygwin shell with python fooTests.py it produces:
$ python fooTests.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
But when I'm editing fooTests.py within IDLE and I do Run -> Run Module, the new Python Shell spawned by IDLE produces:
>>> ================================ 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
>>>
What am I doing wrong, to produce this traceback, and especially how can I fix it so that I can just do Run->Run Module (or F5) within IDLE to run the unit tests quickly?
(This surely must be a simple question, but my quick attempts to figure it out have proven fruitless.)
No one answered (I find that if there aren't any answers in the first few minutes, the likelihood of an answer goes down significantly :), so I kept researching this myself.
Not sure if this is the most elegant solution or not, but changing:
if __name__ == '__main__':
unittest.main()
to
if __name__ == '__main__':
try: unittest.main()
except SystemExit: pass
seemed to do the trick.
I guess the problem is that (according to http://coding.derkeiler.com/Archive/Python/comp.lang.python/2003-11/0239.html) the unittest module finishes by calling sys.exit which is apparently problematic for IDLE since it wants to keep the Python shell running, whereas it's not a problem when you run it from the command line, which expects to dump you back to your already-running command line anyway.
I don't know if this solution, catching the SystemExit event and ignoring it, is problematic at all, but it seems to work for the all-tests-pass and some-tests-fail cases I checked.
Also: see this StackOverFlow Post: What code can I use to check if Python is running in IDLE? , which provides a test to see whether the program is being run from within IDLE or not.
You can also do
if __name__ == '__main__':
unittest.main(exit=False)
if you're using Python >= 2.7
Something like this should also work:
suite = unittest.TestLoader().loadTestsFromTestCase( fooTests )
unittest.TextTestRunner(verbosity=2).run( suite )
I found that here, and it worked for me.
精彩评论