我有这样的测试设置:

def test1():
    with Manager1() as m1, m1.get_m2() as m2:
        do_test1(m1, m2)

def test2():
    with Manager1() as m1, m1.get_m2() as m2:
        do_test2(m1, m2)


我用nosetests运行。现在事实证明,上下文管理器的__enter__()__exit__()方法很昂贵,因此我想更改为以下设置:

def test():
    with Manager1() as m1, m1.get_m2() as m2:
        do_test1(m1, m2)
        do_test2(m1, m2)


但我还是希望鼻子每次检查都要分别报告。我研究了模块级别和类级别的setup()teardown()方法,但是在出现异常的情况下,它们似乎没有提供相同的清除保证。是否有一种干净的方法来使nose与上下文管理器进行协作?

最佳答案

如果您担心setup中引发的异常导致无法调用teardown方法,则可以在ExitStack中使用contextlib类。如果ExitStack中发生异常,则setup可以确保正确关闭您的经理类。

from io import StringIO
from contextlib import ExitStack

managers = []
close_managers = None

def setup():
    global close_managers
    with ExitStack() as exit_stack:
        managers[:] = [exit_stack.enter_context(StringIO()) for _ in range(2)]
        # any exception raised before this line will will cause all the __exit__
        # methods of the given context managers to be called. So this should
        # be the last part of setup
        close_managers = exit_stack.pop_all().close

def teardown():
    m1, m2 = managers
    assert m1.getvalue() == 'test1 m1\ntest2 m1\n'
    assert m2.getvalue() == 'test1 m2\ntest2 m2\n'
    close_managers()

def test1():
    m1, m2 = managers
    m1.write('test1 m1\n')
    m2.write('test1 m2\n')

def test2():
    m1, m2 = managers
    m1.write('test2 m1\n')
    m2.write('test2 m2\n')

关于python - 在同一上下文管理器中执行多个测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32189666/

10-12 21:18