因此,我需要构建大量带有缓存的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
表示被修饰的函数request
,这样我就可以引用该对象将内容存储在缓存中我觉得有一些组合应该是可行的——我只是还不明白。request
和func
的要求对于如何传入/引用这些对象似乎是一成不变的。我想我不能把它们结合起来。
非常感谢您的帮助!
所以我想明白了。我将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')