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

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

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

根据测试用例执行情况,决定测试结束要不要将环境下电,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根据用例执行情况控制夹具执行不同的代码

http://www.jsqmd.com/news/200543/

相关文章:

  • 【珍藏干货】LangGraph年度学习总结:三大维度+三层架构,构建完整AI Agent知识体系
  • 关注地下水与地表水安全:农业 N/P 面源污染迁移机制、模拟方法与减排实践,从剖面淋失到区域负荷:农业面源污染评估的 N/P 迁移模拟进阶路径
  • 竞赛毕业设计定制作品---【芳心科技】F. 基于单片机摩托车发动机温度控制系统设计
  • 46、线程邮箱系统(C语言+多线程通信)
  • 如何在 Ubuntu 22.04 服务器上通过 Ansible 自动化管理 Docker 容器,简化部署与更新流程?
  • 提升多模态AI项目效率:GLM-4.6V-Flash-WEB快速上手经验分享
  • 通过ADB调试远程服务器上的GLM-4.6V-Flash-WEB实例
  • 结合JavaScript前端实现GLM-4.6V-Flash-WEB图像识别结果可视化
  • GLM-4.6V-Flash-WEB模型支持WebSocket实时交互吗?
  • 【必收藏】从Manus被收购看AI Agent架构:6大核心模块Python代码全实现(附完整代码)
  • GLM-4.6V-Flash-WEB模型实战:图文理解与图像问答的低延迟解决方案
  • 竞赛毕业设计定制作品---【芳心科技】F. 基于单片机的泡茶机
  • GLM-4.6V-Flash-WEB模型是否支持增量学习或微调?
  • 让小模型逆袭!RouteRAG端到端强化学习实现文本/图谱智能检索,收藏必学!
  • wangEditor pdf导入识别图表和文本高亮
  • 城市热岛效应研究:GLM-4.6V-Flash-WEB分析红外遥感数据
  • 存储型跨站脚本攻击剖析:HTML上下文(无编码防护)
  • 从Python到C++的无缝衔接:C++精灵库,开启少儿编程新篇章
  • 使用Flask包装GLM-4.6V-Flash-WEB模型提供HTTP服务
  • [Windows] 卸载软件Uninstall Tool3.8.0
  • 收藏!2025智能体元年:企业级AI平台构建12大核心经验全攻略
  • GLM-4.6V-Flash-WEB模型与LangChain框架集成的可能性分析
  • GLM-4.6V-Flash-WEB模型在文物数字化保护中的辅助作用
  • 噪声污染分布:GLM-4.6V-Flash-WEB关联街景与声学传感器
  • 架构设计必藏!知识图谱+向量数据库=GraphRAG:构建可扩展、可信AI系统的终极解决方案
  • 程序员必看!一文读懂LLM、RAG、Agent,建议收藏反复阅读
  • GLM-4.6V-Flash-WEB模型的安全性评估:是否存在隐私泄露风险?
  • 2026执业药师考试备考培训机构哪家好?这三家高口碑机构抓紧关注! - 医考机构品牌测评专家
  • WinForms + DevExpress中documentManager中的tites对象图片圆角
  • GLM-4.6V-Flash-WEB模型二次开发入门指南:接口调用与扩展建议