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.
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.
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.)
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
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!
To avoid the end of execution traceback:
if __name__ == '__main__':
unittest.main(exit=False)