Is it possible for a unit test to assert that a method calls sys.exit()?

PythonUnit Testing

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

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)

 

sys.exit Documentation:

> Exit from Python. This is implemented by raising the SystemExit exception ... it is possible to intercept the exit attempt at an outer level.

Solution 2 - Python

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)

Solution 3 - Python

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.

Solution 4 - Python

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")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTravis BearView Question on Stackoverflow
Solution 1 - PythonPavel AnossovView Answer on Stackoverflow
Solution 2 - PythonTravis BearView Answer on Stackoverflow
Solution 3 - PythonsleepykyleView Answer on Stackoverflow
Solution 4 - PythonbinarysubstrateView Answer on Stackoverflow