我有一个具有以下结构的测试:
def test_foo(test_cases):
for case in test_cases:
run_test(case)
每个run_test
都相当慢,如果案例失败,再次调用测试将从头开始循环。
因此,我会在状态文件中跟踪最后一个失败的循环变量,如下所示:
def test_foo(test_cases, state_file):
states_dic = load_state_file(state_file)
for case in itertools.dropwhile(
lambda c : 'foo' in state_dic and state_dic['foo'] != c,
test_cases):
states_dic['foo'] = case
try:
run_test(case)
except Exception:
save_state_file(states_dic, state_file)
raise
states_dic.pop('foo', None)
save_state_file(states_dic, state_file)
我想知道是否有更通用的方法来实现从状态恢复循环。到目前为止,我想出的是这种模式:
def test_foo(test_cases, state_file):
with ResumableIterator(test_cases, 'foo', state_file) as itercases:
for case in itercases:
run_test(case)
其中ResumableIterator
是一个上下文管理器,可以跟踪加载并将状态'foo'
保存到state_file
。它将产生一个迭代器,它由第一个参数构成,它跟踪它发出的最后一个值,这样当循环异常时,它会将最后一个发出的值保存在状态文件中。有更好的想法吗?
答案 0 :(得分:0)
不确定这是否比您的上下文管理器方法更好,但它可能更简单一点,只有一个run
而不是__enter__
和(通常很无聊)__exit__
。< / p>
# python 3
class TestRunner:
def __init__(self, *test_cases):
self.queue = list(test_cases)
def run(self):
for i, case in enumerate(self.queue):
try:
run_test(case)
except Exception as e:
print(e)
self.queue = self.queue[i:]
break
出于演示目的,让我们说
def run_test(case):
case()
runner = TestRunner(
lambda: print('case 1'),
lambda: print('case 2'),
lambda: print(im_not_defined),
lambda: print('case 4')
)
然后你只需调用run
方法来运行测试:
>>> runner.run()
case 1
case 2
name 'im_not_defined' is not defined
>>> runner.run() # resume from last failure; will fail again since we didn't fix it
name 'im_not_defined' is not defined
>>> runner.queue[0] = lambda: print('case 3 fixed')
>>> runner.run()
case 3 fixed
case 4