微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Unittest中通过setUp和tearDown替换python with_statement

如何解决在Unittest中通过setUp和tearDown替换python with_statement

一个测试套件中,我有一些组织如下的代码,上下文是一些持久对象,当退出c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lcurl块时,该持久对象将被删除

with

很明显,在两个测试中,代码都重复了安装样板,因此我想使用setUp()和tearDown()方法来分解该样板。

但是我不知道如何提取with_statement。我想到的是这样的:

class Test(TestCase):
    def test_action1(self):
        with create_context() as context:
            context.prepare_context()
            context.action1()
            self.assertTrue(context.check1())
            
    def test_action2(self):
        with create_context() as context:
            context.prepare_context()
            context.action2()
            self.assertTrue(context.check2())

但是我认为当测试失败时,这并不完全等效,而且必须在tearDown()中放置一个明确的删除也感觉不正确。

将with_statement代码更改为setUp()和tearDown()样式的正确方法是什么?

解决方法

我不确定100%是否对setUp()和tearDown()感兴趣,但是在上下文管理器__enter____exit__中定义的方法听起来像它们在执行您想要的操作(只是名称不同):

class ContextTester():
    def __enter__(self):
        self.context = create_context()
        self.context.prepare_context()
        return self.context

    def __exit(self,exc_type,exc_value,exc_traceback):
        self.context.close()

def Test(TestCase):
    def test_action1(self):
        with ContextTester() as context:
            context.action1()
            self.assertTrue(context.check1())
            
,

您可能要为此使用contextlib.ExitStack

一种上下文管理器,旨在使其通过编程轻松组合其他上下文管理器和清除功能,尤其是那些可选的或由输入数据驱动的清除功能。

import contextlib
from unittest import TestCase


class Test(TestCase):
    def setUp(self) -> None:
        stack = contextlib.ExitStack()
        self.context = stack.enter_context(create_context())  # create_context is your context manager
        self.addCleanup(stack.close)

    def test_action1(self):
        self.context.prepare_context()
        self.context.action1()
        self.assertTrue(self.context.check1())

或者如果您想对拆卸进行控制或使用多个上下文管理器,那就更好了

import contextlib
from unittest import TestCase


class Test(TestCase):
    def setUp(self):
        with contextlib.ExitStack() as stack:
            self.context = stack.enter_context(create_context())  # create_context is your context manager
            self._resource_stack = stack.pop_all()

    def tearDown(self):
        self._resource_stack.close()

    def test_action1(self):
        self.context.prepare_context()
        self.context.action1()
        self.assertTrue(self.context.check1())

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。