在Python

时间:2016-02-23 21:30:18

标签: 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。它将产生一个迭代器,它由第一个参数构成,它跟踪它发出的最后一个值,这样当循环异常时,它会将最后一个发出的值保存在状态文件中。有更好的想法吗?

1 个答案:

答案 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