首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

pytest的内置插件盘点5:fixtures

5. 内置插件 fixtures

插件路径:_pytest.fixtures

实现的 hook

调用的 hook

pytest_fixture_setup

pytest_fixture_post_finalizer

插件功能

创建文件配置项:usefixtures,用来强制用例自动使用 fixture

创建装饰器@pytest.fixture,用来申明 fixture:_pytest.fixtures.FixtureFunctionMarker

创建插件funcmanage,用来收集、管理 fixture:_pytest.fixtures.FixtureManager

创建 fixturerequest,用来使用 fixture,_pytest.fixtures.FixtureRequest

代码片段

class FixtureRequest:

def _get_active_fixturedef( self, argname: str ) -> Union["FixtureDef[object]", PseudoFixtureDef[object]]: try: return self._fixture_defs[argname] except KeyError: try: fixturedef = self._getnextfixturedef(argname) except FixtureLookupError: if argname == "request": cached_result = (self, [0], None) return PseudoFixtureDef(cached_result, Scope.Function) raise

@fixture(scope="session")def pytestconfig(request: FixtureRequest) -> Config:

return request.config

def call_fixture_func( fixturefunc: "_FixtureFunc[FixtureValue]", request: FixtureRequest, kwargs) -> FixtureValue: if is_generator(fixturefunc): fixturefunc = cast( Callable[..., Generator[FixtureValue, None, None]], fixturefunc ) generator = fixturefunc(**kwargs) try: fixture_result = next(generator) except StopIteration: raise ValueError(f"{request.fixturename} did not yield a value") from None finalizer = functools.partial(_teardown_yield_fixture, fixturefunc, generator) request.addfinalizer(finalizer) else: fixturefunc = cast(Callable[..., FixtureValue], fixturefunc) fixture_result = fixturefunc(**kwargs) return fixture_result

fixture 插件提供了个 fixture 叫requests,实现方式非常有趣

没有用@pytest.fixture的方式进行创建

拦截用例请求的 fixture 名,如果是request的话,就把自己给出去

通过返回值,使自己的 scope 成为 session 级

pytestconfig才是第一个用@pytest.fixture创建的 fixture

fixture 的执行细节:

如果是函数 fixture:直接调用,返回结果,没有 teardown 阶段

如果是生成器 fixture

setup + 返回值 :按照迭代器协议调用

teardown:调用request.addfinalizer委托给 runner 插件

简评

funcmanage 和 session 插件都是【由插件创建的插件】,虽然露面的挺早,但是加载的很晚,

尤其 funcmanage,它是最后一个被加载的 pytest 内置插件。

...

在使用 fixture 时,我们不说【调用】fixture,而是说【请求】fixture。

因为在使用时,pytest 都会根据上下文判断,是重新调用 fixture 取结果,还是直接返回上一次的结果

也就是说,你使用的时候能够拿到 fixture 返回值,但是不确定有没有进行调用。

...

使用yield为 fixture 添加 teardown 是更加直接、更干净推荐方案,。

相反,request.addfinalizer是一种偏底层的写法,应该小心使用,可能会出现 setup 异常,却依然尝试 teadrown 的糟糕局面

note:生成器 fixture 是在 setup 成功才调用 request.addfinalizer,所以能避免这种情况

...

fixture 相关的内容太多了,比如:

怎么从各个地方找到 fixture、

怎么处理同名 fixture 优先级的,

怎么处理参数的,

怎么进行参数化的,

怎么验证 fixture 之间的范围关系

等等。。。

这些留到介绍 funcmanage 插件的时候再细说吧,如果还是说不完,就再单独开一个 fixture 章节。

...

我在上篇文章中提到:

有些提供了 hook 实现

有些插件提供了 fixture 实现

有些插件提供了 hook 和 fixture 实现

pytest中,fixture和hook同为最重要的特性之一,

对于还未掌握 hook 的人来说,用好 fixure 可以拉进你和 pytest 的距离

对于已经掌握 hook 的人来说,用好 fixure 可以拉进你和用例的距离

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OKsrK4LbdHPp1wEbanMmSXlQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券