Python 在同一上下文管理器中执行多个测试
我有这样的测试设置:Python 在同一上下文管理器中执行多个测试,python,nose,contextmanager,Python,Nose,Contextmanager,我有这样的测试设置: 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) 我使用鼻测试运行它。现在,上下文管理器的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()和\uuuuuuuu
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)
我使用鼻测试运行它。现在,上下文管理器的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
def test():
with Manager1() as m1, m1.get_m2() as m2:
do_test1(m1, m2)
do_test2(m1, m2)
但我还是想为每个测试单独报告。我研究了模块级和类级的setup()
和teardown()
方法,但它们似乎没有为异常情况下的清理提供相同的保证。是否有一种干净的方法让nose
与上下文管理器协作 看看鼻子。如果您将代码更改为使用yield,这可能会起作用,例如:
from nose.tools import nottest
@nottest
def do_test1(m1, m2):
m1.write('do_test1 f1')
m2.write('do_test1 f2')
@nottest
def do_test2(m1, m2):
m1.write('do_test2 f1')
m2.write('do_test2 f2')
def test():
with open('f1.txt', 'wb') as m1, open('f2.txt', 'wb') as m2:
yield do_test1, m1, m2
yield do_test2, m1, m2
运行测试可以让您:
$ nosetests context.py -v
context.test(<open file 'f1.txt', mode 'wb' at 0x06A5BF40>, <open file 'f2.txt', mode 'wb' at 0x06A5BF98>) ... ok
context.test(<open file 'f1.txt', mode 'wb' at 0x06A5BF40>, <open file 'f2.txt', mode 'wb' at 0x06A5BF98>) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.004s
OK
$nostests context.py-v
context.test(,)。。。好啊
context.test(,)。。。好啊
----------------------------------------------------------------------
在0.004s中运行了2次测试
好啊
如果您担心在设置中引发异常,导致拆卸方法无法调用,则可以在中使用该类。如果在设置
中出现异常,则ExitStack
可以确保您的manager类正确关闭
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')
谢谢,这是一个好主意,但我想我将失去选择性地运行单个测试的能力,例如:nosetests.py:test1
,我也希望保留它。或者你也知道如何保存它吗?另外,请看一下感谢链接,但节目结束语是:“关于这种技术的一个警告:可以调用上下文管理器的\uuuuuu exit\uuuu
方法,其中包含有关正在进行的异常的信息。这里显示的机制永远不会这样做。”如果像nose
这样的库阻止我们将与
块一起使用,那么ExitStack
似乎就是使用上下文管理器进行正确异常处理的一种方法。谢谢,这似乎正是ExitStack
的确切用例(位于python2的contextlib2包中)。可以很好地确保在m1.get\u m2()
引发异常时仍调用m1.\uu exit()
,同时保留nosetests
的所有功能。