繁体   English   中英

如何将 pytest 固定装置与 Unittest 方法一起使用

[英]How to use pytest fixtures with Unittest methods

class MyTestCase(unittest.Testcase):
    def setUp(self):
        self.something = True

    @pytest.fixture(autouse=True)
    def MyTestMethod(self, frozentime):
        fn(self.something)  # self.something is NOT defined

如果我使用@pytest.fixture(autouse=True)我最终会得到一些来自 PyTest 的奇怪行为。 PyTest 没有在测试方法之前调用我的setUp方法,而是跳过setUp并调用MyTestMethod ,就好像它是一个 PyTest MyTestFunction ,这当然不能很好地工作。

如何在不忽略应首先调用的setUp方法的情况下让MyTestMethod使用frozentime装置。

class MyTestCase(unittest.Testcase):
    def setUp(self):
        self.something = True

    #@pytest.fixture(autouse=True)
    def MyTestMethod(self, frozentime): # Fails on call, because it needs too many arguments.
        fn(self.something)  

这是因为 autouse 夹具在setUp / tearDown方法之前执行:

笔记

由于两个框架之间的架构差异,基于unittest的测试的设置和拆卸是在测试的call阶段执行的,而不是在pytest的标准setupteardown阶段执行。 在某些情况下,理解这一点很重要,尤其是在推理错误时。 例如,如果基于unittest的套件在设置期间出现错误,则pytest在其setup阶段不会报告任何错误,而是会在call期间引发错误。

来源

您无法解决这种行为。 您可以将与夹具相关的代码移出setUp / tearDown方法,例如:如果在类范围的夹具中使用了self.flag则可以替换

class Tests(unittest.TestCase):

    def setUp(self):
        self.flag = True

    def tearDown(self):
        self.flag = False

    @pytest.fixture(autouse=True)
    def myfixture(self):
        print(self.flag)

class Tests(unittest.TestCase):

    @pytest.fixture(autouse=True)
    def prepare_flag(self):
        self.flag = True
        yield
        self.flag = False

    @pytest.fixture(autouse=True)
    def myfixture(self, prepare_flag):
        print(self.flag)

或者你可以将所有setUp从灯具相关的代码:

class Tests(unittest.TestCase):

    def setUp(self):
        self.flag = True

    @pytest.fixture(autouse=True)
    def myfixture(self, somearg):
        fn(self.flag, somearg)

变成

class Tests(unittest.TestCase):

    def setUp(self):
        self.flag = True
        fn(self.flag, self._somearg)

    @pytest.fixture(autouse=True)
    def assign_stuff(self, somearg):
        self._somearg = somearg

正如@hoefling 所提到的,这两个生命周期是不兼容的……但是如果您的目标不是直接兼容,那么这可能会被破解。

import pytest
from pytestqt.plugin import QtBot
from unittest import TestCase
from myproject import custom_widget

@pytest.fixture(scope="class")
def qtbot_adapter(qapp, request):
    """Adapt qtbot fixture for usefixtures and unittest.TestCase"""
    request.cls.qtbot = QtBot(request)

def with_updown(function):
    """Wrapper to bodge setUp/tearDown into fixtures+TestCase"""
    def test_wrapper(self, *args, **kwargs):
        __tracebackhide__ = True
        if callable(getattr(self, 'up', None)):
            self.up()
        try:
            function(self, *args, **kwargs)
        finally:
            if callable(getattr(self, 'down', None)):
                self.down()
    test_wrapper.__doc__ = function.__doc__

    return test_wrapper

@pytest.mark.usefixtures("qtbot_adapter")
class MyTestCase(TestCase):
    def up(self):
        self.widget = custom_widget.CustomWidget()
        self.widget.show()

    @with_updown
    def test_some_property(self):
        with self.qtbot.waitSignal(self.widget.my_signal,
                                   timeout=300):
            self.widget.do_thing()
        self.assertEqual(self.widget.get_thing(), 'foo')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM