python-3.x - 如何捕获动态调用的函数中引发的异常?

标签 python-3.x

我分心了,最终用 python 编写了一个测试框架。我正在努力解决这个问题。

在断言期间,我想抛出一个异常,作为将问题冒泡到 run_test() 方法的一种方式,而不要求用户对框架有任何了解。问题是,当我这样做时,似乎没有遵守 try/catch block 。

这是我刚刚起步的框架的精简版本:

# test_framework.py
import inspect
import module_containing_tests

class AssertionException(Exception):
    def __init__(self, message):
        self.message = message
    def __str__(self):
        return self.message

def run_test(test_name, test_method):
    try:
        print(">", test_name)
        test_method()
        print("Passed")
    except AssertionException as error:
        print("Failed")
        print(str(error))

def assert_true(conditional):
    if not conditional:
        raise AssertionException("Expected True. Was False")

def test(func):
    func.is_test = True
    return func

members = inspect.getmembers(module_containing_tests)
for member in members:
    if "is_test" in dir(member[1]) and not member[0] == "module_containing_tests":
        run_test(member[0], member[1])

包含测试的模块将如下所示:

# module_containing_tests.py
from test_framework import *

@test
def passing_test():
    assert_true(1 + 2 == 3)

@test
def failing_test():
    assert_true(1 + 2 == 5)

输出中包含所有异常堆栈跟踪,并且还停止执行

λ python test_framework.py
> failing_test
Traceback (most recent call last):
  File "test_framework.py", line 29, in <module>
    run_test(member[0], member[1])
  File "test_framework.py", line 13, in run_test
    test_method()
  File "C:\Git\simpy-test\module_containing_tests.py", line 9, in failing_test
    assert_true(1 + 2 == 5)
  File "C:\Git\simpy-test\test_framework.py", line 20, in assert_true
    raise AssertionException("Expected True. Was False")
test_framework.AssertionException: Expected True. Was False

我想要的是这样的:

λ python test_framework.py
> failing_test
Expected True. Was False
Failed
> passing_test
Passed

最佳答案

我认为问题部分在于两个文件之间的循环引用,这可能会扰乱方法的可见性(以某种方式解释 here ),部分可能在于方法中。如果您考虑有多少其他测试框架在工作,您通常有 3 个元素:要测试的单元、测试框架和测试运行器。

因此,如果我们尝试按照该逻辑拆分所有内容,您最终会得到:

test_framework.py

# test_framework.py
class AssertionException(Exception):
    pass


def test(f):
   f.is_test = True
   return f


def assert_true(conditional):
    if not conditional:
        raise AssertionException("Expected True. Was False")

test_runner.py

# test_runner.py
import inspect

import unit_test
from test_framework import AssertionException


def run_test(test_name, test_method):
    try:
        print(">", test_name)
        test_method()
        print("Passed")
    except AssertionException as error:
        print("Failed with AssertionException: " + str(error))
    except Exception as error:
        print("Failed with Exception: " + str(error))


if __name__ == "__main__":
    members = inspect.getmembers(unit_test)
    for member in members:
        if "is_test" in dir(member[1]):
            run_test(member[0], member[1])

unit_test.py

# unit_test.py
from test_framework import *


@test
def a_passing_test():
    assert_true(1 + 2 == 3)


@test
def z_failing_test():
    assert_true(1 + 2 == 5)

通过此设置,循环依赖被删除,所有可见性上下文都得到尊重,并且输出/行为是预期的。

希望对您有所帮助。

关于python-3.x - 如何捕获动态调用的函数中引发的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48575241/

相关文章:

python - Mysql 不适用于 python 3.6 和 django 1.9

arrays - 数据转换警告: A column-vector y was passed when a 1d array was expected

python - if block 的可读性

python-3.x - 如何打印预测图像的置信度

python - 使用 Gunicorn 进行预测时无法解开对象

python - 从大型 unicode 文本文件中删除符号

python - cx_Freeze 和 Python 的各种 build_exe_options 是什么?

python - 从停止的地方重新运行 python 脚本

Python 3,解析json

python - pandas如何计算仅给定月份和日期的增量