带有缓存和自定义装饰器的pytest fixture



因此,我需要构建大量带有缓存的pytest设备。我认为,尝试构建一个能够容纳fixture中所有公共逻辑的decorator(主要是获取和设置缓存(将减少启动新fixture所需的代码量。

这是我迄今为止所拥有的。

def cached_resource(name):
def decorator_cached_resource(func):
def request_wrapper(request):
@functools.wraps(func)
def wrapper(*args, **kwargs):
resource = request.config.cache.get(f'resources/{name}', None)
if not resource:
resource = func(*args, **kwargs)
request.config.cache.set(f'resources/{name}', resource)
return resource
return wrapper
return request_wrapper
return decorator_cached_resource

@pytest.fixture(scope='session')
@cached_resource(name='identity-provider')
def cached_identity_provider():
return app.identity_providers.create(name='test')
@pytest.fixture(scope='session')
@cached_resource(name='token')
def cached_token(cached_identity_provider):
return app.identity_providers.tokens.create(
identity_provider_id=cached_identity_provider['id'],
token_expiration_days=60
)

我觉得我已经接近了,但我的断言失败了。我没有返回dict,而是返回函数本身。

def test_create(cached_identity_provider):
>       assert isinstance(cached_identity_provider, dict)
E       assert False
E        +  where False = isinstance(<function cached_identity_provider at 0x1057a8310>, dict)

我需要以下要求/对象来实现这一点。

缓存资源的name,以便我可以将其正确存储在缓存中
  • func表示被修饰的函数
  • 来自pytest的request,这样我就可以引用该对象将内容存储在缓存中
  • CCD_ 5和CCD_
  • 我觉得有一些组合应该是可行的——我只是还不明白。requestfunc的要求对于如何传入/引用这些对象似乎是一成不变的。我想我不能把它们结合起来。

    非常感谢您的帮助!

    所以我想明白了。我将request更改为pytestconfig,但关键是在fixture方法签名中提供pytestconfig。我过于热衷于从固定装置签名中删除参数。

    def cached_resource(name):
    def decorator_cached_resource(func):
    @functools.wraps(func)
    def wrapper(pytestconfig, *args, **kwargs):
    resource = pytestconfig.cache.get(f'resources/{name}', None)
    if not resource:
    resource = func(pytestconfig, *args, **kwargs)
    pytestconfig.cache.set(f'resources/{name}', resource)
    return resource
    return wrapper
    return decorator_cached_resource
    
    @pytest.fixture(scope='session')
    @cached_resource(name='identity-provider')
    def cached_identity_provider(pytestconfig):
    return app.identity_providers.create(name='pythonapiwrappertest')
    

    最新更新