news 2026/9/3 0:43:25

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

作者头像

张小明

前端开发工程师

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/9/3 0:19:26

2026必备10个降AIGC工具,研究生必看!

2026必备10个降AIGC工具,研究生必看! AI降重工具:论文优化的得力助手 在当前学术研究日益依赖人工智能技术的背景下,越来越多的研究生发现,使用AI生成的内容在查重系统中容易被标记为高AIGC率。这不仅影响论文的通过率…

作者头像 李华
网站建设 2026/9/2 23:26:40

FastStone Capture注册码不再难找:搭配GLM-4.6V-Flash-WEB做截图识别

FastStone Capture注册码不再难找:搭配GLM-4.6V-Flash-WEB做截图识别 在日常软件使用中,激活界面里的注册码总是那串最“刺眼”的字符——既不能复制,又容易看错。尤其是面对像 O 和 0、l 和 1 这类形似字符时,手动输入不仅耗时&a…

作者头像 李华
网站建设 2026/9/1 0:43:28

GLM-4.6V-Flash-WEB模型二次开发入门指南:接口调用与扩展建议

GLM-4.6V-Flash-WEB模型二次开发入门指南:接口调用与扩展建议 在当前AI应用加速落地的浪潮中,多模态能力正成为智能系统的核心竞争力。无论是电商平台的商品图像理解、教育领域的图文解析,还是内容平台的自动化审核,开发者都迫切需…

作者头像 李华
网站建设 2026/8/28 21:06:49

GLM-4.6V-Flash-WEB模型在快递包裹识别中的自动化应用

GLM-4.6V-Flash-WEB模型在快递包裹识别中的自动化应用 在物流分拣中心的传送带上,每天有成千上万的包裹高速流转。一张张面单被摄像头快速抓拍——有的褶皱、有的反光、有的字迹模糊,甚至夹杂着手写备注和涂改痕迹。传统OCR系统面对这些“非标准输入”时…

作者头像 李华
网站建设 2026/8/28 19:23:49

如何为GLM-4.6V-Flash-WEB模型添加中文语音输出功能?

如何为GLM-4.6V-Flash-WEB模型添加中文语音输出功能? 在智能交互系统日益普及的今天,用户对AI的期待早已不再局限于“能看懂图”或“能回答问题”,而是希望它真正具备“会说话”的能力。尤其是在教育辅助、无障碍服务和智能家居等场景中&…

作者头像 李华
网站建设 2026/8/31 18:29:11

GLM-4.6V-Flash-WEB模型一键推理脚本使用说明(附Jupyter操作路径)

GLM-4.6V-Flash-WEB 模型部署实践:从一键脚本到交互式开发 在多模态AI快速落地的今天,一个核心挑战始终摆在开发者面前:如何让强大的视觉语言模型真正“跑得起来”?不是停留在论文里的指标,也不是依赖昂贵GPU集群的演示…

作者头像 李华