如何为 python 中的非失败方法编写至少执行一次 except 块的测试用例

How to write test case for executing except block at least once for a non-failing method in python

我创建了一个 python class 如下 -

class MyClass:
    mydict = {}
    error = None
    traceback = None
    message = None

    def create_log_message(self, **kwargs):
        try:
            error = kwars.get("error", self.error)
            traceback = kwargs.get("traceback", self.traceback)
            message = kwargs.get("message", self.message)
            self.mydict = {"error": error, "traceback": traceback, "message": message}
            return self.mydict
        except Exception as e:
            error = e
            traceback = tb.format_exc()
            message = kwargs.get("message", self.message)
            self.mydict = {"error": error, "traceback": traceback, "message": message}
            return self.mydict

下面是我的测试class -

import unittest import TestCase
import traceback as tb
import MyClass
class TestMyClass(TestCase):
    def test_success(self):                                       # Test in case of success
        inst = MyClass()
        mydict = inst.create_log_message(message="success")
        self.assertEqual(mydict["error"], None)
        self.assertEqual(mydict["traceback"], None)
        self.assertEqual(mydict["message"], "success")
 
    def test_failure(self):                                       # test in case of exception
        try:
            1/0
        except ArithmeticError as e:
            error = e
            traceback = tb.format_exc()
            inst = MyClass()
            mydict = inst.create_log_message(error=error, traceback=traceback, message="failure")
            self.assertEqual(mydict["error"], error)
            self.assertEqual(mydict["traceback"], traceback)
            self.assertEqual(mydict["message"], "failure")

    def test_no_args(self):                                       # test for no argument being passed
        inst = MyClass()
        mydict = inst.create_log_message()
        self.assertEqual(mydict["error"], None)
        self.assertEqual(mydict["traceback"], None)
        self.assertEqual(mydict["message"], None)

    def test_extra_args(self):                                    # test for any other argument
        inst = MyClass()
        mydict = inst.create_log_message(name="test")
        with self.assertRaises(KeyError):
            self.assertEqual(mydict["name"], "test")
        self.assertEqual(mydict["error"], None)
        self.assertEqual(mydict["traceback"], None)
        self.assertEqual(mydict["message"], None)

我的问题是 MyClass 中的块甚至一次都没有被调用,即使我没有传递参数、匹配参数或任何 other/extra 参数,因此代码覆盖率失败(未达到 100%),如何通过测试用例至少执行一次 except 块?我正在使用 python3.8x/ubuntu20.04.

在这方面的任何帮助都会很有帮助:)

PS:如果我遗漏了任何细节,请原谅,因为这是我第一次 post 堆栈溢出。

如果你想测试失败的案例,你可以尝试unittest.mock。如果将异常传递给模拟的 side_effect 参数,则会引发此异常。

文档:https://docs.python.org/3/library/unittest.mock.html

但首先考虑可能发生此异常的真实情况并尝试模拟此情况。如果无法引发异常,则无需在代码中处理它。

首先,你真的需要那个 except 子句吗?你在处理什么错误? try 块中的代码不会引发任何异常,因此无法引发异常。我不会专注于如何测试该代码,而只是将其删除。你不需要它。

except 块未被执行,因为您在 MyClass 的 try 块中提到默认值为 None,即 kwars.get("error", self.error)。只需删除默认值,它就会起作用。

class MyClass:
mydict = {}
error = None
traceback = None
message = None

def create_log_message(self, **kwargs):
    try:
        error = kwargs["error"]
        traceback = kwargs["traceback"]
        message = kwargs["message"]
        self.mydict = {"error": error, "traceback": traceback, "message": message}
        return self.mydict
    except Exception as e:
        error = e
        traceback = tb.format_exc()
        error = kwargs.get("error", self.error)
        traceback = kwargs.get("traceback", self.traceback)
        message = kwargs.get("message", self.message)
        self.mydict = {"error": error, "traceback": traceback, "message": message}
        return self.mydict