Is it possible for a unit test to assert that a method calls sys.exit()?
Question:
I have a Python 2.7 method that sometimes calls
sys.exit(1)
Is it possible to make a unit test that verifies this line of code is called when the right conditions are met?
Answers:
Yes. sys.exit
raises SystemExit
, so you can check it with assertRaises
:
with self.assertRaises(SystemExit):
your_method()
Instances of SystemExit
have an attribute code
which is set to the proposed exit status, and the context manager returned by assertRaises
has the caught exception instance as exception
, so checking the exit status is easy:
with self.assertRaises(SystemExit) as cm:
your_method()
self.assertEqual(cm.exception.code, 1)
Exit from Python. This is implemented by raising the SystemExit
exception … it is possible to intercept the exit attempt at an outer level.
Here’s a complete working example. In spite of Pavel’s excellent answer, it took me a while to figure this out, so I’m including it here in the hope that it will be helpful.
import unittest
from glf.logtype.grinder.mapping_reader import MapReader
INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"
class TestMapReader(unittest.TestCase):
def test_get_tx_names_incomplete_mapping_file(self):
map_reader = MapReader()
with self.assertRaises(SystemExit) as cm:
tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
self.assertEqual(cm.exception.code, 1)
As an additional note to Pavel’s excellent answer, you can also check for specific statuses if they’re provided in the function you’re testing. For example, if your_method()
contained the following sys.exit("Error")
, it would be possible to test for "Error" specifically:
with self.assertRaises(SystemExit) as cm:
your_method()
self.assertEqual(cm.exception, "Error")
I found the answer to your question in the Python Unit Testing documentation search for “Testing for Exceptions”. Using your example, the unit test would look like the following:
self.assertRaises(SystemExit, your_function, argument 1, argument 2)
Remember to include all arguments needed to test your function.
I have a Python 2.7 method that sometimes calls
sys.exit(1)
Is it possible to make a unit test that verifies this line of code is called when the right conditions are met?
Yes. sys.exit
raises SystemExit
, so you can check it with assertRaises
:
with self.assertRaises(SystemExit):
your_method()
Instances of SystemExit
have an attribute code
which is set to the proposed exit status, and the context manager returned by assertRaises
has the caught exception instance as exception
, so checking the exit status is easy:
with self.assertRaises(SystemExit) as cm:
your_method()
self.assertEqual(cm.exception.code, 1)
Exit from Python. This is implemented by raising the
SystemExit
exception … it is possible to intercept the exit attempt at an outer level.
Here’s a complete working example. In spite of Pavel’s excellent answer, it took me a while to figure this out, so I’m including it here in the hope that it will be helpful.
import unittest
from glf.logtype.grinder.mapping_reader import MapReader
INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"
class TestMapReader(unittest.TestCase):
def test_get_tx_names_incomplete_mapping_file(self):
map_reader = MapReader()
with self.assertRaises(SystemExit) as cm:
tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
self.assertEqual(cm.exception.code, 1)
As an additional note to Pavel’s excellent answer, you can also check for specific statuses if they’re provided in the function you’re testing. For example, if your_method()
contained the following sys.exit("Error")
, it would be possible to test for "Error" specifically:
with self.assertRaises(SystemExit) as cm:
your_method()
self.assertEqual(cm.exception, "Error")
I found the answer to your question in the Python Unit Testing documentation search for “Testing for Exceptions”. Using your example, the unit test would look like the following:
self.assertRaises(SystemExit, your_function, argument 1, argument 2)
Remember to include all arguments needed to test your function.