在 Python 中编写一个可恢复循环



我有一个具有以下结构的测试:

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。 它将产生一个从第一个参数构造的迭代器,该迭代器跟踪它发出的最后一个值,以便在循环异常时,它将最后一个发出的值保存在状态文件中。 有什么更好的主意吗?

不确定这是否比您的上下文管理器方法更好,但它可能更简单一些,只有一个run而不是__enter__和(通常很无聊的)__exit__

# 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

相关内容

最新更新