保山市网站建设_网站建设公司_模板建站_seo优化
2026/1/7 10:57:19 网站建设 项目流程

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询