如何将 pytest.mark 装饰器包装在另一个装饰器中并维护所有属性?

How can I wrap pytest.mark decorator in another decorator and maintain all properties?

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

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

   def test_stuff(self):
      pass

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

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

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

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

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

有没有办法修改我的装饰器以保持 属性 如果应用于 class,它会应用于所有 class 的测试?重申一下,我的装饰器 确实 在个人测试级别工作,但在 class 级别破坏了东西。

我把这个严重地复杂化了。

您可以保留 @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