20

I'm using Python's unittest library and all the tests succeed, but I still get a traceback and I can't understand how I can fix the problem.

........
----------------------------------------------------------------------
Ran 8 tests in 0.020s

OK

Traceback (most recent call last):
  File "C:\Users\Paul\Desktop\bloomfilter\test_bloomfilter.py", line 85, in <module>
    unittest.main()
  File "C:\Programming\PythonX86\Python27\lib\unittest\main.py", line 95, in __init__
    self.runTests()
  File "C:\Programming\PythonX86\Python27\lib\unittest\main.py", line 231, in runTests
    sys.exit(not self.result.wasSuccessful())
SystemExit: False
>>> 
Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • 1
    Does [this](http://stackoverflow.com/questions/79754/unittest-causing-sys-exit) help any? [For example, passing exit=False to main.) – DSM Feb 08 '12 at 22:55

5 Answers5

21

To avoid the end of execution traceback:

if __name__ == '__main__':
    unittest.main(exit=False)
Ratmir Asanov
  • 6,237
  • 5
  • 26
  • 40
Florent B.
  • 41,537
  • 7
  • 86
  • 101
16

It appears that you are running in the Python shell, which catches exceptions for you so you can continue debugging. If you had been running from the command line, the line

sys.exit(not self.result.wasSuccessful())

would have exited your program with an exit code of 0, which indicates success (this might be counterintuitive if you're unfamiliar with how programs interact with the shell). Since you're running in the interpreter, however, the exception is caught.

I would suggest that there is nothing wrong with your program or your tests. The unittests framework probably just didn't expect to be run interactively!

mattbornski
  • 11,895
  • 4
  • 31
  • 25
7

end your unittest file with:

if __name__=='__main__':
    try:
        unittest.main()
    except SystemExit as inst:
        if inst.args[0] is True: # raised by sys.exit(True) when tests failed
            raise
Remi
  • 20,619
  • 8
  • 57
  • 41
3

sys.exit(not self.result.wasSuccessful())

I ran into this when I assumed my __main__.py in my Python package would always have the __name__, "__main__" - but when I ran my unittests through discovery there, I found that they would be executed but with a different __name__ - "package.__main__".

Therefore I did need the following in my __main__.py just like in simple Python scripts:

if __name__ == '__main__':
    main()

instead of just

main()

If the main is unittest.main, call it with

if __name__ == '__main__':
    main(exit=False)

if you want the process to stick around in interactive mode if you're calling

python -im package_name

If you're using:

python -m unittest discover 

then I don't think exit=False should matter.

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
1

Whatever you're using to run these tests, it's catching the SystemExit exception and printing the traceback. When you write code that catches exceptions, you should take care to not catch exceptions that you don't actually want to catch, like SystemExit (raised by sys.exit() to end the program) and usually KeyboardInterrupt (raised by control-C.)

Thomas Wouters
  • 130,178
  • 23
  • 148
  • 122