Is it possible to check if a program stopped with sys.exit() and check for the messages that were logged using the logging module?
For example, let’s say I have the following function in a file called func.py:
import logging
import sys
logging.basicConfig(level=logging.INFO,format='%(levelname)s:%(message)s')
def my_func(word):
    if word == "orange":
        logging.info("All is good with {}.".format(word))
    elif word == "apple":
        logging.error("Something went wrong with {}.".format(word))
        sys.exit()
Now, I have created a couple of tests to check my function’s performance. I know that, to test the messages logged–provided that the program completed its function–I can do something like this:
import unittest
from func import *
class Test_errors_and_messages(unittest.TestCase):
    def test_logs(self):
        with self.assertLogs() as captured:
            my_func("orange")
        self.assertEqual(len(captured.records), 1)
        self.assertEqual(captured.records[0].getMessage(), "All is good with orange.")
And if I want to check if the program is stopping when expected, I’m doing something similar to this:
import unittest
from func import *
class Test_errors_and_messages(unittest.TestCase):
    def test_exit(self):
        with self.assertRaises(SystemExit):
            my_func("apple")
My question is: is it possible to test for a system exit and the messages logged at the same time? In other words, I would like to modify the test_exit() test to check (a) that the program stopped with a SystemExit and (b) that the message
Something went wrong with apple.
was logged. In particular, I want to check both of these conditions because in my real script, I have several conditions that will prompt sys.exit(), and I want to test that when the program stops, it is stopping for the reason that I expect.
Advertisement
Answer
Just put the two context managers together:
with self.assertLogs() as captured, self.assertRaises(SystemExit):
    my_func("apple")
# assert on captured logs here
