【问题标题】:How can I wrap pytest.mark decorator in another decorator and maintain all properties?如何将 pytest.mark 装饰器包装在另一个装饰器中并维护所有属性?
【发布时间】:2021-06-04 08:40:48
【问题描述】:

Pytest 有一个装饰器,允许您将元数据传递给测试。您可以将装饰器应用于一个类,该类会将其应用于该类中的所有测试。您还可以将装饰器应用于单个测试,如下所示:

@pytest.mark.resources('a')
class FooTests:
   ...

   def test_stuff(self):
      pass

   @pytest.mark.resources('a','b','c')
   def test_something(self):
      pass

在此示例中,类级别的resources 元数据应用于所有测试,内部pytest.mark.resources 覆盖类级别声明。

我正在尝试编写一个装饰器来保持这种行为。到目前为止,这就是我所拥有的:

def set_resources(*args):
    def wrapper(func):
        @pytest.mark.resources(*args)
        def inner(*args, **kwargs):
            func(*args, **kwargs)
        return inner
    return wrapper

现在我可以像这样装饰测试:

@set_resources('a','b','c')
def test_foo(self):
   pass

它按预期工作。但是,尝试在类级别应用我的自定义装饰器是行不通的。事实上,当我在类级别应用自定义装饰器时,PyTest 发现不再发现类中的任何测试,这让我相信我的装饰器在某种程度上污染了整个过程。

有没有办法修改我的装饰器以维护如果应用于一个类,它适用于所有该类的测试的属性?重申一下,我的装饰器确实在单个测试级别工作,但在类级别破坏了一些东西。

【问题讨论】:

    标签: python pytest python-decorators python-3.8


    【解决方案1】:

    我严重地过度复杂了。

    您可以保留 @pytest.mark.resources('a','b','c', ...) 装饰器的行为,只需在包装它的函数中返回它,如下所示:

    def set_resources(*args):
       return pytest.mark.resources(*args)
    

    然后按预期工作:

    @set_resources('a','b','c')
    class SomeTests:
    
       @set_resources('a')
       def test_doing_stuff(self):
          assert True
    

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 2016-07-23
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 2021-10-24
      相关资源
      最近更新 更多