news 2026/10/15 23:50:34

根据上一个测试用例的执行结果决定某一夹具的使用情况

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
根据上一个测试用例的执行结果决定某一夹具的使用情况

根据上一个测试用例的执行结果决定某一夹具的使用情况

根据测试用例执行情况,决定测试结束要不要将环境下电,pytest的夹具实现和python的条件控制好像区别不大的样子

目标效果

目前我是写了一个电源控制的夹具,原本的设计思路:将夹具作为参数传入测试用例,测试用例执行完就执行控制电源动作。

现在由于某些情况,测试过程中会出现异常情况,我想要根据测试用例的执行情况,动态的调整电源的控制情况。

假如测试用例失败或者根据某一个参数的变化,让测试结束后不要关闭电源。如果测试流程顺利则关闭电源

原本的夹具定义:

""" 调用此夹具执行需要进行参数传入,需要控制的电源名,根据电源名进行电源控制 在测试结束时会下发关闭电源的命令 """@pytest.fixture(scope='function')defpdu(request):pdu_name=request.param# 初始化一个电源控制类yieldprint(f'关闭电源{pdu_name}')# 关闭电源
实现思路

通过优化夹具逻辑和参数传递实现

  1. 写一个获取测试结果的钩子函数,确保夹具能拿到用例执行状态;
  2. 让夹具支持接收多参数(如 PDU 名称、强制保电标识等),兼顾 “参数变化” 的判断维度;
  3. 封装核心判断逻辑:同时校验 “测试结果” 和 “自定义参数”,只有满足 “测试成功 + 无强制保电” 时才关闭电源。

目录结构如下:

新夹具实现如下:

importsysimportpytestimportos PROJECT_PATH=os.path.abspath(os.path.join(__file__,'..','..'))sys.path.append(PROJECT_PATH)fromcfg.set_logimportlogger# 钩子函数:保存测试用例执行结果到测试节点@pytest.hookimpl(tryfirst=True,hookwrapper=True)defpytest_runtest_makereport(item,call):outcome=yieldrep=outcome.get_result()# 将测试结果(call阶段:用例执行阶段)保存到itemsetattr(item,"test_result",rep.outcome)@pytest.fixture(scope='function')defpdu(request):# 解析传入的参数(支持多参数传递)param=request.param pdu_name=param.get("pdu_name")# 可选参数:是否强制保电(默认False)keep_power_on=param.get("keep_power_on",False)logger.info('pdu begin')logger.info(f'pdu name:{pdu_name}')yieldtest_result=request.node.test_resultifkeep_power_onortest_result!="passed":# 需要加电源的具体操作,可以选择封装成一个类,调用其方法reason="强制保电"ifkeep_power_onelsef"测试{test_result}"logger.info(f"【电源策略】{reason},保留PDU{pdu_name}供电")else:logger.info(f"【电源策略】测试成功,关闭PDU{pdu_name}")

测试用例如下:

importpytest# 场景1:测试成功 + 无强制保电 → 关闭电源@pytest.mark.parametrize("pdu",[{"pdu_name":"pdu_01"}],indirect=True)deftest_success_normal(pdu):assert1+1==2# 测试通过# 场景2:测试失败 → 不关闭电源@pytest.mark.parametrize("pdu",[{"pdu_name":"pdu_02"}],indirect=True)deftest_failed_case(pdu):assert1+1==3# 测试失败# 场景3:测试成功 + 强制保电 → 不关闭电源@pytest.mark.parametrize("pdu",[{"pdu_name":"pdu_03","keep_power_on":True}],indirect=True)deftest_success_keep_power(pdu):assert1+1==2# 测试通过,但强制保电# 场景4:测试跳过 → 不关闭电源@pytest.mark.skip(reason="临时跳过")@pytest.mark.parametrize("pdu",[{"pdu_name":"pdu_04"}],indirect=True)deftest_skipped_case(pdu):assertTrue

在实现夹具之前,先封装一个logger,用于收集日志,实现仅供参考

# set_log.pyimportloggingfromlogging.handlersimportRotatingFileHandlerimportosimportsysfromdatetimeimportdatetimedefsetup_logger(name:str="pdu_test",# 日志器名称,默认区分不同模块log_level:str="INFO",# 日志级别:DEBUG/INFO/WARNING/ERROR/CRITICALlog_dir:str=None,# 日志文件目录,默认项目根目录下的logsmax_bytes:int=10*1024*1024,# 单个日志文件最大大小(10MB)backup_count:int=5,# 日志文件备份数量(最多保留5个)console_output:bool=True# 是否输出到控制台)->logging.Logger:""" 封装日志配置函数,返回配置好的logger实例 :param name: 日志器名称(区分不同模块,如"pdu_control"、"br_cmd") :param log_level: 日志级别,字符串类型(兼容大小写) :param log_dir: 日志文件保存目录,默认项目根目录/logs :param max_bytes: 单个日志文件最大字节数(默认10MB) :param backup_count: 日志文件备份数(默认保留5个) :param console_output: 是否输出到控制台(默认开启) :return: 配置好的logger对象 """# 1. 初始化logger,避免重复添加handler导致日志重复输出logger=logging.getLogger(name)logger.setLevel(log_level.upper())# 统一转大写,兼容小写输入logger.handlers.clear()# 清空已有handler,防止重复输出# 2. 定义日志格式(包含时间、级别、模块、行号、日志内容)log_format=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",datefmt="%Y-%m-%d %H:%M:%S"# 时间格式)# 3. 配置文件输出Handler(按大小轮转)ifnotlog_dir:# 默认日志目录:项目根目录/logsproject_root=os.path.abspath(os.path.join(os.path.dirname(__file__),".."))log_dir=os.path.join(project_root,"logs")# 自动创建日志目录(不存在则创建)os.makedirs(log_dir,exist_ok=True)# 日志文件名:按日期命名(如2026-01-05_pdu_test.log)log_filename=f"{datetime.now().strftime('%Y-%m-%d')}_{name}.log"log_file_path=os.path.join(log_dir,log_filename)# 配置轮转文件Handlerfile_handler=RotatingFileHandler(filename=log_file_path,mode="a",# 追加模式maxBytes=max_bytes,backupCount=backup_count,encoding="utf-8"# 编码,避免中文乱码)file_handler.setFormatter(log_format)logger.addHandler(file_handler)# 4. 配置控制台输出Handler(可选)ifconsole_output:console_handler=logging.StreamHandler(sys.stdout)console_handler.setFormatter(log_format)logger.addHandler(console_handler)returnlogger# ---------------------- 快捷获取logger的方式 ----------------------# 全局通用logger(默认配置)logger=setup_logger(name="pdu_power_control")# 按模块拆分的logger(可选)pdu1_logger=setup_logger(name="pdu1",log_level="DEBUG")pdu2_logger=setup_logger(name="pdu2",log_level="INFO")

各位大佬,还有其他比较优雅的实现方式吗?

原文:救命!!!这个功能应该怎么实现?pytest根据用例执行情况控制夹具执行不同的代码

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 14:32:34

GLM-4.6V-Flash-WEB模型在内容安全审核中的实际应用效果

GLM-4.6V-Flash-WEB模型在内容安全审核中的实际应用效果 如今,一条带图的社交媒体动态可能藏着比文字更深的“雷”——一张看似普通的健身照配上一句“加微信看私密视频”,就能绕过大多数基于关键词或图像分类的传统审核系统。这种图文协同违规的现象&am…

作者头像 李华
网站建设 2026/10/15 15:27:09

SpringMVC大文件上传的断点续传功能实现原理

大三党毕业设计救星:10G大文件上传加密断点续传(原生JSSpringBoot) 兄弟,作为山西某高校软工专业的大三老狗,我太懂你现在的处境了——毕业设计要做文件管理系统,甲方(老师)要10G大…

作者头像 李华
网站建设 2026/10/15 8:34:00

火箭发射台检查:GLM-4.6V-Flash-WEB识别耐热材料脱落

火箭发射台检查:GLM-4.6V-Flash-WEB识别耐热材料脱落 在航天发射任务日益频繁的今天,火箭点火瞬间喷涌而出的高温燃气流温度可超过3000℃,对发射台导流槽和火焰挡板表面的耐热涂层形成剧烈冲刷。这种极端工况下,哪怕是一小块陶瓷基…

作者头像 李华
网站建设 2026/10/15 9:52:47

GLM-4.6V-Flash-WEB模型支持WebSocket实时交互吗?

GLM-4.6V-Flash-WEB 模型与 WebSocket 实时交互的融合实践 在当今多模态AI快速演进的背景下,用户不再满足于“上传图片、等待结果”的静态交互模式。越来越多的应用场景——比如智能客服中的视觉问答、教育平台上的图像解析辅导、辅助技术中的实时图像描述——都要求…

作者头像 李华
网站建设 2026/10/15 18:35:53

RAG vs CAG:大模型知识增强技术实战对比,收藏级深度解析

文章详细对比了大语言模型两种知识增强技术:检索增强生成(RAG)通过实时检索外部数据库提供最新信息,适合动态知识场景;缓存增强生成(CAG)通过预加载和缓存机制提高响应速度,适合稳定知识场景。RAG优势在于实时更新、降低幻觉&…

作者头像 李华
网站建设 2026/10/15 14:00:36

空气质量反演:GLM-4.6V-Flash-WEB结合光学与激光雷达图像

空气质量反演:GLM-4.6V-Flash-WEB结合光学与激光雷达图像 在京津冀地区某次重污染天气过程中,环保部门发现多个地面监测站的数据变化趋势不一致——有的站点PM2.5浓度飙升,而相邻区域却相对平稳。这种“跳跃式”的数据分布暴露了一个长期困扰…

作者头像 李华