Brian Paden
Brian Paden

Reputation: 1351

Unittest causing sys.exit()

No matter what I do sys.exit() is called by unittest, even the most trivial examples. I can't tell if my install is messed up or what is going on.

IDLE 1.2.2      ==== No Subprocess ====
>>> import unittest
>>> 
>>> class Test(unittest.TestCase):
        def testA(self):
            a = 1
            self.assertEqual(a,1)

>>> unittest.main()
option -n not recognized
Usage: idle.pyw [options] [test] [...]

Options:
  -h, --help       Show this message
  -v, --verbose    Verbose output
  -q, --quiet      Minimal output

 Examples:
   idle.pyw                               - run default set of tests
   idle.pyw MyTestSuite                   - run suite 'MyTestSuite'
   idle.pyw MyTestCase.testSomething      - run MyTestCase.testSomething
   idle.pyw MyTestCase                    - run all 'test*' test methods
                                           in MyTestCase

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    unittest.main()
  File "E:\Python25\lib\unittest.py", line 767, in __init__
    self.parseArgs(argv)
  File "E:\Python25\lib\unittest.py", line 796, in parseArgs
    self.usageExit(msg)
  File "E:\Python25\lib\unittest.py", line 773, in usageExit
    sys.exit(2)
SystemExit: 2
>>> 

Upvotes: 21

Views: 10770

Answers (6)

dmeister
dmeister

Reputation: 35614

In new Python 2.7 release, unittest.main() has a new argument.

If 'exit' is set to False, sys.exit() is not called during the execution of unittest.main().

Upvotes: 31

Aaron Hall
Aaron Hall

Reputation: 394995

It's nice to be able to demonstrate that your tests work when first trying out the unittest module, and to know that you won't exit your Python shell. However, these solutions are version dependent.

Python 2.6

I'm using Python 2.6 at work, importing unittest2 as unittest (which is the unittest module supposedly found in Python 2.7).

The unittest.main(exit=False) doesn't work in Python 2.6's unittest2, while JoeSkora's solution does, and to reiterate it:

unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(Test))

To break this down into its components and default arguments, with correct semantic names for the various composed objects:

import sys # sys.stderr is used in below default args

test_loader = unittest.TestLoader()
loaded_test_suite = test_loader.loadTestsFromTestCase(Test)
                                           # Default args:
text_test_runner = unittest.TextTestRunner(stream=sys.stderr,
                                           descriptions=True, 
                                           verbosity=1)
text_test_runner.run(loaded_test_suite)

Python 2.7 and 3

In Python 2.7 and higher, the following should work.

unittest.main(exit=False)

Upvotes: 6

Joe Skora
Joe Skora

Reputation: 14920

Your example is exiting on my install too. I can make it execute the tests and stay within Python by changing

unittest.main()

to

unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(Test))

More information is available here in the Python Library Reference.

Upvotes: 15

try:
    sys.exit()
except SystemExit:
    print('Simple as that, but you should really use a TestRunner instead')

Upvotes: 2

John Millikin
John Millikin

Reputation: 200796

Pop open the source code to unittest.py. unittest.main() is hard-coded to call sys.exit() after running all tests. Use TextTestRunner to run test suites from the prompt.

Upvotes: 5

Allen
Allen

Reputation: 5110

Don't try to run unittest.main() from IDLE. It's trying to access sys.argv, and it's getting the args that IDLE was started with. Either run your tests in a different way from IDLE, or call unittest.main() in its own Python process.

Upvotes: 10

Related Questions