是否有一种在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_
开头的任何内容都被脚本视为失败点,并且根据配置文件启用/禁用失败。你觉得怎么样?
答案 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)