测试夹具:
这个装饰器 @pytest.fixture(scope="class", autouse=True) 是 Python 测试框架 pytest 中非常强大的组合,主要用于定义测试夹具(Fixture)。
@pytest.fixture: 基础定义
scope="class": 作用域(生命周期)
autouse=True: 自动执行
1. 核心含义拆解
scope="class" (类级作用域)
含义: 这个 fixture 在整个测试类的生命周期中只执行一次。
执行时机:
Setup (前置): 在该类中的第一个测试方法运行之前执行。
Teardown (后置): 在该类中的最后一个测试方法运行完毕后执行(如果有 yield 语句)。
对比: 默认的 scope="function" 是每个测试方法运行前都会执行一次。
autouse=True (自动调用)
含义: 你不需要在测试方法(如 def test_xxx(self))的参数中显式请求这个 fixture,也不需要用 @pytest.mark.usefixtures 装饰。
效果: 只要测试类被执行,这个 fixture 就会自动生效。
2. 总结:它的整体作用
当你在一个方法上加上 @pytest.fixture(scope="class", autouse=True) 时,意味着:
“在运行这个类里面的任何测试之前,请自动帮我执行这段代码;等这个类里所有测试都跑完了,再帮我清理环境。而且,这一切都不需要我在测试函数里手动调用。”
3.fixture内容一般在conftest.py (共享机制) 中
·这是一个特殊的文件。定义在 conftest.py 里的 fixture,无需 import 就可以在同级及子目录下的所有测试文件中直接使用。
4. 应用场景
这种配置通常用于资源昂贵且需要类级别共享的初始化操作,例如:
数据库连接: 为一个测试类开启一个数据库连接,所有测试方法共用这个连接,最后关闭。
浏览器启动 (Selenium/Playwright): 打开一次浏览器,在这个类里做多个页面的操作测试,最后关闭浏览器。
加载大型配置文件/数据集: 读取一次大文件,供类中所有方法读取。
跳过执行用例
根据前面在初始化类或每一条用例中的变量值进行跳过操作
背景:目前项目由多个,有一部分用例的某一个或几个项目需要执行,其他项目不需要执行,所以需要设置跳过执行的功能。 如果在执行前就确认执行的是哪个项目就非常简单,用最基础的skip方法即可,看最后一份代码,但我采用的动态获取,原理是在conftest中,从某些值中动态判断车型种类,并赋值变量,所以需要第一种方法。
最终可实现方法如下:
a:
import pytest from loguru import logger class Test_A: #setup_class 类中初始化一次,此处可省略,但是由于实际中我的框架必须要用到夹具,所以先保留 @pytest.fixture(scope = "class", autouse = True) def setup_class(self, ): logger.info(" == = 测试开始 == = ") def setup_method(self): # def setup_method(self,obj): 每条用例前执行 self.vec_obj = "robo" # 实际是 obj.ipd.vec_obj # self.if_robo = self.vec_obj == "robo" def test_camera_drive(self): if self.vec_obj == "robo" : pytest.skip("运行时条件不满足,跳过测试") assert True def test_ccccccccc(self): if self.if_robo: assert True else: pytest.skip("运行时条件不满足,跳过测试") if __name__ == '__main__': pytest.main(["-v", "-s", __file__])b 在 setup_class中也可以,但是不能使用 @pytest.fixture(scope = "class", autouse = True) 不然就不生效了
import pytest from loguru import logger class Test_A: #setup_class 类中初始化一次 def setup_class(self): # def setup_class(self,obj): 每条用例前执行 self.vec_obj = "robo" # 实际是 obj.ipd.vec_obj # self.if_robo = self.vec_obj == "robo" def test_camera_drive(self): if self.vec_obj == "robo" : pytest.skip("运行时条件不满足,跳过测试") assert True def test_ccccccccc(self): if self.if_robo: assert True else: pytest.skip("运行时条件不满足,跳过测试") if __name__ == '__main__': pytest.main(["-v", "-s", __file__])跳过用例执行的,基础用法介绍:
import pytest import sys @pytest.mark.skip(reason="此功能在V2.0版本才实现,暂不执行") # 无条件跳过 def test_a(): assert False # 根据Python版本跳过 @pytest.mark.skipif(sys.version_info < (3, 8), reason="需要Python 3.8或更高版本") def test_b(): assert True # 根据自定义条件跳过(例如,环境变量或配置) is_production = True @pytest.mark.skipif(is_production, reason="生产环境下不运行此破坏性测试") def test_c(): assert 1==2 if __name__ == '__main__': pytest.main(["-v", "-s", __file__])