单元测试是否可以断言方法调用sys.exit()

问题:单元测试是否可以断言方法调用sys.exit()

我有一个python 2.7方法,有时会调用

sys.exit(1) 

当满足正确的条件时,是否可以进行单元测试以验证是否调用了此代码行?

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?


回答 0

是。sys.exit加注SystemExit,因此您可以使用以下命令进行检查assertRaises

with self.assertRaises(SystemExit):
    your_method()

的实例SystemExit具有code设置为建议的退出状态的属性,并且由返回的上下文管理器assertRaises将捕获的异常实例设置为exception,因此检查退出状态很容易:

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

sys.exit文档

从Python退出。这是通过引发SystemExit异常来实现的…可以在外部级别拦截出口尝试。

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.


回答 1

这是一个完整的工作示例。尽管Pavel给出了出色的回答,但我还是花了一些时间才弄清楚这一点,因此我将其包含在此处,希望对您有所帮助。

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)

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)

回答 2

我在Python单元测试文档搜索“测试异常”中找到了您问题的答案。使用您的示例,单元测试如下所示:

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

记住要包括测试功能所需的所有参数。

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.


回答 3

作为Pavel出色答案的补充说明,如果您正在测试的功能中提供了特定状态,您还可以检查特定状态。例如,如果your_method()包含以下内容,sys.exit("Error")则可以专门测试“错误”:

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")

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