Python失败注入

时间:2013-01-10 10:20:18

标签: python testing

是否有一种在Python脚本中注入失败的简洁方法?我想避免使用以下内容来填充源代码:

failure_ABC = True
failure_XYZ = True
def inject_failure_ABC():
    raise Exception('ha! a fake error')
def inject_failure_XYZ():
    # delete some critical file
    pass

# some real code
if failure_ABC:
    inject_failure_ABC()
# some more real code
if failure_XYZ:
    inject_failure_XYZ()
# even more real code

修改 我有以下想法:插入“失败点”作为特制的评论。编写一个将在Python解释器之前调用的简单解析器,并将生成具有实际失败代码的实际检测Python脚本。 E.g:

#!/usr/bin/parser_script_producing_actual_code_and_calls python
# some real code
# FAIL_123
if foo():
    # FAIL_ABC
    execute_some_real_code()
else:
    # FAIL_XYZ
    execute_some_other_real_code()

FAIL_开头的任何内容都被脚本视为失败点,并且根据配置文件启用/禁用失败。你觉得怎么样?

3 个答案:

答案 0 :(得分:2)

在测试错误处理时,最好的方法是隔离可能在测试中覆盖的新方法中抛出错误的代码:

class ToTest:
    def foo(...):
        try:
            self.bar() # We want to test the error handling in foo()
        except:
            ....

    def bar(self):
        ... production code ...

在您的测试用例中,您可以扩展ToTest并使用抛出您要测试的异常的代码覆盖bar()

编辑您应该考虑将大型方法拆分为较小的方法。它将使代码更易于测试,理解和维护。有关如何更改开发过程的一些想法,请查看Test Driven Development

关于您使用“失败评论”的想法。这看起来是个很好的解决方案。有一个小问题:您必须编写自己的Python解析器,因为Python在生成字节码时不会保留注释。

因此,您可以花费几周的时间来写这个或几周,以使您的代码更容易测试。

但是有一点不同:如果你不一直走,那么解析器将毫无用处。此外,花费的时间也不会改善您的代码。大部分工作将进入解析器和工具。因此,在所有这些时间之后,您仍然需要改进代码,添加失败注释并编写测试。

通过重构代码,您可以随时停止,但到目前为止所花费的时间将是有意义的而不是浪费。您的代码将在您做出的第一个更改后开始变得更好,并且会不断改进。

编写一个复杂的工具需要花费时间,它将有自己的错误,需要修复或解决。这些都不会在短期内改善你的情况,你也无法保证它会改善长期。

答案 1 :(得分:2)

您可以使用模拟库,例如unittest.mock,也存在许多第三方库。然后,您可以模拟代码使用的某些对象,以便抛出异常或以您希望的方式运行。

答案 2 :(得分:1)

如果您只想在某个时候停止代码,并回到交互式解释器,可以使用:

assert 1==0

但是这只有在你不用-O

运行python时才有效

修改 实际上,我的第一个答案是快速,没有真正理解你想做什么,抱歉。

如果通过参数进行参数化,而不是通过变量/函数就足够了,也许你的代码已经变得更具可读性了。像

这样的东西
failure = {"ABC": False, "XYZ":False}

#Do something, maybe set failure

def inject_failure(failure):
    if not any(failure.values()):
        return
    if failure["ABC"]:
        raise Exception('ha! a fake error')
    elif failure["XYZ"]:
        # delete some critical file
        pass

inject_failure(failure)