views:

219

answers:

2

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 shell 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.)

+1  A: 

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.

Chirael
A: 

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.

MikeWyatt