当前位置: 首页 > wzjs >正文

网络营销专员岗位职责seo网络推广排名

网络营销专员岗位职责,seo网络推广排名,网站开发报价表模板,阿里云新增网站文章目录 问题分析将属性绑定到 **类** 上使用 scopefunction 解决方法为什么有两个不同的对象核心原因:fixture 的执行上下文scopefunction 的情况scopeclass 的情况 为什么 pytest 要这样做?这是 pytest 的设计局限 总结 本文探讨 Pytest 中 fixture 作…

文章目录

      • 问题
      • 分析
        • 将属性绑定到 **类** 上
        • 使用 `scope='function'`
      • 解决方法
      • 为什么有两个不同的对象
        • 核心原因:fixture 的执行上下文
          • `scope='function'` 的情况
          • `scope='class'` 的情况
        • 为什么 pytest 要这样做?
        • 这是 pytest 的设计局限
      • 总结

本文探讨 Pytest 中 fixture 作用域与类继承的交互问题,介绍其执行顺序规则。
以 TestBase 类和 TestDerived 子类为例,指出当 init 函数的 fixture 作用域设为 class 时会出现子类无法使用 self.base 的情况,原因是 fixture 和测试方法在不同实例对象上执行。

在 pytest 中,通常情况下,fixture 的执行顺序主要由 scope 决定,但并非简单地"高级别先执行"。实际上,pytest 按照一种"由外到内"的方式执行不同 scope 的 fixture。

具体来说,fixture 执行顺序遵循以下规则:

  1. 首先按照 scope 从大到小的顺序执行:session > package > module > class > function
  2. 同一 scope 级别的 fixture 按照依赖关系执行:如果一个 fixture 依赖于另一个 fixture(通过参数引用),则先执行被依赖的 fixture
  3. 同一 scope 级别且无依赖关系的 fixture 按照它们在代码中的声明顺序执行

问题

下面是 pytest 中 fixture 作用域(scope)与 Python 类继承之间的交互方式导致的一个问题。

这个代码 TestBase 中,如果将 init 函数使用级别为 function 的scope 运行没问题,但是改成 class 级别后,子类中的方法就没使用 self.base 了。

import pytestclass TestBase:# @pytest.fixture(scope='class', autouse=True)  # 在 test_derived 中无法使用 self.base@pytest.fixture(scope='function', autouse=True)  # 可行def init(self):self.base = "base"class TestDerived(TestBase):def test_derived(self):assert self.base == "base"def test_derived2(self):assert self.base == "base"

分析

fixture 的触发机制问题

  • 对于 autouse=True 的 fixture,pytest 需要确定何时以及在哪个对象上执行它
  • 当 fixture 定义在类内部且使用 scope='class' 时,pytest 可能在处理 fixture 的执行上下文时出现了问题
将属性绑定到
import pytestclass TestBase:@pytest.fixture(scope='class', autouse=True)def init(self, request):print(f"Init fixture executing, self is: {self}")print(f"Request.cls is: {request.cls}")request.cls.base = "base"  # 确保设置在类上而不是实例上class TestDerived(TestBase):def test_derived(self):print(f"In test_derived, self is: {self}")print(f"self.__class__.base is: {getattr(self.__class__, 'base', 'NOT_FOUND')}")assert hasattr(self.__class__, 'base')assert self.__class__.base == "base"assert self.base == "base"

执行结果:

============================== 1 passed in 0.10s ==============================
Init fixture executing, self is: <src.practice_demo.te.TestDerived object at 0x0000026EA6DE32E0>
Request.cls is: <class 'src.practice_demo.te.TestDerived'>
PASSED                                  [100%]
In test_derived, self is: <src.practice_demo.te.TestDerived object at 0x0000026EA6E50760>
self.__class__.base is: base

可以发现:

  1. fixture 确实执行了Init fixture executing 说明 scope='class' 的 fixture 被正确触发
  2. 执行顺序没问题:fixture 先执行,然后才是测试方法
  3. 对象实例不同:注意两个关键的内存地址
    • fixture 中的 self: 0x0000026EA6DE32E0
    • 测试方法中的 self: 0x0000026EA6E50760

这就解释了为什么原始代码会失败,当使用类内部定义的 scope='class' fixture 时:

  • fixture 在一个 TestDerived 实例上执行(地址 2E0),设置了 self.base = "base"
  • 但测试方法 test_derived 在另一个不同的 TestDerived 实例上执行(地址 760
  • 这两个是完全不同的对象实例

解决:使用 request.cls.base = "base" 将属性设置在上而不是实例上,所以无论哪个实例都能访问到这个类属性。

使用 scope='function'

因为 function 级别的 fixture 会在每个测试方法的同一个实例上执行,所以 self.base 设置和访问都在同一个对象上。

class TestBase:@pytest.fixture(scope='function', autouse=True)def init(self):print(f"Init fixture executing, self is: {self}")self.base = 'base'class TestDerived(TestBase):def test_derived(self):print(f"In test_derived, self is: {self}")assert self.base == "base"

运行结果,地址相同:

============================== 1 passed in 0.10s ==============================
Init fixture executing, self is: <src.practice_demo.t.TestDerived object at 0x00000238DC562A90>
PASSED                                   [100%]
In test_derived, self is: <src.practice_demo.t.TestDerived object at 0x00000238DC562A90>

解决方法

使用类属性代替实例属性

如果 base 是类级别的共享状态,可以将其设置为类属性,而不是实例属性:

class TestBase:@pytest.fixture(scope='class', autouse=True)def init(self, request):request.cls.base = "base"  # 设置类属性class TestDerived(TestBase):def test_derived(self):assert self.base == "base"def test_derived2(self):assert self.base == "base"
  • 在这里,request.cls 指向当前测试类(TestDerived),通过 request.cls.base 设置类属性。
  • 这样,base 成为 TestDerived 的类属性,所有的实例都可以通过 self.base 访问。

或者,保持使用 function 级别,这确实更符合 Python 类实例的工作方式,因为每个测试方法实际上都是在一个新的类实例上运行的。

为什么有两个不同的对象

使用 scope='function'情况下,因为 function 级别的 fixture 会在每个测试方法的同一个实例上执行,所以 self.base 设置和访问都在同一个对象上。

但是,为啥 scope 为 class 时,会出现两个对象呢?

这与 pytest 的 fixture 执行机制Python 类方法调用机制 有关。

核心原因:fixture 的执行上下文

当在类内部定义 fixture 时,pytest 需要在某个对象实例上调用这个 fixture 方法。但是:

scope='function' 的情况
  1. pytest 为每个测试方法创建一个新的 TestDerived 实例
  2. 在这个实例上调用 init fixture
  3. 然后在同一个实例上调用测试方法
  4. 流程:创建实例 → 调用 fixture → 调用测试方法(都在同一个对象上)
scope='class' 的情况
  1. pytest 需要在类级别执行 fixture,但 fixture 仍然是一个实例方法
  2. pytest 创建一个 TestDerived 实例来调用 init fixture
  3. 但当执行具体的测试方法时,pytest 又创建了另一个新的实例
  4. 流程:创建实例A → 调用 fixture → 创建实例B → 调用测试方法
为什么 pytest 要这样做?

这实际上是 pytest 设计的一个特点(或者说是限制),打印对象 id :

import pytestclass TestBase:@pytest.fixture(scope='class', autouse=True)def init(self):print(f"\nFixture executing on instance: {id(self)}")self.base = "base"class TestDerived(TestBase):def test_derived(self):print(f"\nTest executing on instance: {id(self)}")print(f"hasattr(self, 'base'): {hasattr(self, 'base')}")if hasattr(self, 'base'):print(f"self.base: {self.base}")else:print("self.base does not exist")# assert hasattr(self, 'base')  # 这行会失败,先注释掉

运行这个代码:

Fixture executing on instance: 1523376596880
PASSED                                  [100%]
Test executing on instance: 1523376597312
hasattr(self, 'base'): False
self.base does not exist
这是 pytest 的设计局限

pytest 在处理类内部定义的 scope='class' fixture 时,无法很好地协调实例的生命周期。这就是为什么通常建议:

  1. 避免在类内部定义 class 级别的 fixture
  2. 将 class 级别的 fixture 定义在 conftest.py 中
  3. 或者使用 request.cls 来操作类属性而不是实例属性

所以看到的"两个对象"现象是 pytest 内部机制导致的,而不是 Python 或测试逻辑的问题。这也解释了为什么这种用法容易出现意想不到的行为。

总结

  • scope='function' 有效是因为 init 方法在每个测试函数运行时都会为当前实例设置 self.base
  • scope='class' 失败是因为 init 方法的 self 没有正确绑定到 TestDerived 的实例上,导致 self.base 未被设置。
  • 通过调整为类属性,可以解决这个问题。
http://www.dtcms.com/wzjs/65292.html

相关文章:

  • 帝国cms做下载网站郑州抖音推广
  • 济南seo怎么优化安徽seo推广
  • 伊宁市住房与城乡建设局网站宁波网站推广公司报价
  • 建电商网站东莞网站建设推广品众
  • 网站建设的一般费用搜索引擎优化实训心得
  • 专门做折扣的网站100条经典广告语
  • 产品做网站推广怎么注册电商平台
  • 返利网网站怎么做浙江seo公司
  • 做笔记网站网站推广策略有哪些
  • 西安网站开发重庆seo网站运营
  • 制作网页的工具是什么自己如何优化网站排名
  • 东莞网站设计与网站制作seo网站课程
  • 网站推广公司官网关于普通话的手抄报
  • 建立个人网站的目的电商广告网络推广
  • 烟台网站建设力荐企汇互联见效付款网站的设计流程
  • 天津网站建设案例怎么学互联网怎么赚钱
  • 长沙大型网站建设公司知名品牌营销策略
  • 郑州网站制作_郑州网页制作_做网站设计_河南网站制作网网店如何营销推广
  • 兰州网站推广手机网站建设
  • 广州做网站公司培训小红书搜索关键词排名
  • 网站编辑做的准备网站域名查询ip
  • 上海企炬做的网站南京谷歌推广
  • 做网站卖衣服物流包年多少钱百度seo排名推广
  • 网站界面 欣赏标题seo是什么意思
  • 网站用哪些系统做的好处软件推广的渠道是哪里找的
  • 怎么做网站推广临沂下载百度手机助手
  • 谷歌推广方式关键词seo排名怎么做的
  • 东莞中小企业网站制作软件推广赚佣金渠道
  • 廊坊网站建设软文营销文章范文
  • php 自动登录其他网站互联网营销案例