[Pytest][Part 4]多种测试运行方式

实现需求2:

有两种运行测试的方式:

  1. 通过config配置文件运行,测试只需要修改config配置文件
  2. cmdline 运行

这里是新建一个config类来存储所有的测试配置,以后配置有修改的话也只需要修改这个类。

根据目前的测试需求,config中有以下几个属性:

属性作用备注
list_test        按case list的flag,为True时生效
single_test单条运行case的flag,为True时生效
repeat      

case重复运行的次数

risk_analysis高风险case分析功能暂未实现
tester              测试者的用户名,作为测试者发送邮件的收件人
case_list存储测试case集,从这里取出需要运行的测试

具体类代码为:

class TestConfig:"""测试配置管理"""_results_file = "test_results.json"_test_history = {}def __init__(self,list_test=False, single_test=False, repeat=1, case_list=None, risk_analysis=False,tester = None):self.list_test = list_testself.single_test = single_testself.repeat = repeatself.case_list = case_listself.risk_analysis = risk_analysisself.tester = tester

虽然有两种运行脚本的方式,但是通过这两种方式获取的信息都会填充到config这个类中,然后从这个类中读取当前需要运行的配置信息。 默认从配置文件中读取测试信息,当配置文件不存在时,从cmdline中读取测试信息。

图一 配置信息读取流程

最上层代码实现:

    def get_test_config(self, config):"""1. read config from config file2. check flag of test config . if true , read test config from config fileif false , read test config from cmdline:param config: Object of Class TestConfig"""split_str = "="config_list = self.read_config_from_file(CONFIG_FILE)run_from_cfg_file = ast.literal_eval(config_list[0].split(split_str)[1].strip())if run_from_cfg_file:logger.info("reading test config from config file ......")self.parse_settings_to_config(config_list, config)else:self.read_config_from_cmdline(config)logger.info("getting test config from cmdline ......")

读取配置文件

配置文件中包含两类信息:

  1. 当前配置文件是否有效的flag(True or False),后面会根据这个flag来决定读取config file还是cmdline
  2. 测试的具体信息,用于填充TestConfig对象的

代码实现:返回一个包含配置信息的list

    def read_config_from_file(self, file_path):# config_file = "config_file.txt"# # get path of config_file.txt# file_path = os.path.join(os.getcwd(), config_file)config_list = []# check if config file is exist# if self.__file_exist_check(file_path):if self.config_file_status(file_path):try:with open(file_path) as file_handle:lines = file_handle.readlines()for line in lines:config_list.append(line.strip())except FileNotFoundError as e:logger.exception(f"file not found:{e}")except PermissionError as e:logger.exception(f"No permission to read the file:{e}")except Exception as e:logger.exception(f"file not found: {e}")return config_list   # config_list 正确else:logger.error("Config file is not exist....Please check again,Test Stop......")exit()

配置文件config_file.txt的内容为:

 --use_config=False
--list_test=True
--single_test=False
--case_list =test_list.txt
--repeat=15
--risk_analysis=False
--tester=TestUser

判断是否使用配置文件

通过run_from_cfg_file 这个flag来判断是读取配置文件还是读取cmdline

"""flag of run method ,from config file , or from cmdline
"""
run_from_cfg_file = False# config_list 为read_config_from_file()返回的config list
run_from_cfg_file = ast.literal_eval(config_list[0].split(split_str)[1].strip())if run_from_cfg_file:logger.info("reading test config from config file ......")self.parse_settings_to_config(config_list, config)else:self.read_config_from_cmdline(config)logger.info("getting test config from cmdline ......")

若run_from_cfg_file 为True,则从配置文件中读取测试配置并调用方法parse_settings_to_config()填充到TestConfig对象中

# fill test settings to TestConfig objectdef parse_settings_to_config(self, arg_list, config):split_str = "="for item in arg_list:if "--list_test" in item:config.list_test = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--single_test" in item:config.single_test = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--case_list" in item:config.case_list = item.split(split_str)[1].strip()elif "--repeat" in item:config.repeat = item.split(split_str)[1].strip()elif "--risk_analysis" in item:config.risk_analysis = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--tester=TestUser" in item:config.tester = item.split(split_str)[1].strip()

若run_from_cfg_file 为False,则调用方法read_config_from_cmdline()将cmdline中的配置填充到TestConfig配置中去。

 def get_cmdline_args(self):list = sys.argvreturn listdef read_config_from_cmdline(self,config):self.parse_settings_to_config(self.get_cmdline_args(),config)

至此通过配置文件和cmdline分别获取测试配置信息的task就已经完成了。读取配置信息的工作都是在tef_funtcion.py中的class FunctionApi中来完成的。完整代码为:

"""
this file is api preset for test, all test function tool that needed is included in this python file
"""
import ast
import os.path
import sysfrom utils.TestLogger import TestLogger as TestLoggerconfig_file = "config_file.txt"
# get path of config_file.txt
CONFIG_FILE = os.path.join(os.getcwd(), config_file)"""flag of run method ,from config file , or from cmdline
"""run_from_cfg_file = False
logger = TestLogger().get_logger()class FunctionApi:# fill test settings to TestConfig objectdef parse_settings_to_config(self, arg_list, config):split_str = "="for item in arg_list:if "--list_test" in item:config.list_test = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--single_test" in item:config.single_test = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--case_list" in item:config.case_list = item.split(split_str)[1].strip()elif "--repeat" in item:config.repeat = item.split(split_str)[1].strip()elif "--risk_analysis" in item:config.risk_analysis = ast.literal_eval(item.split(split_str)[1].strip())  # transfer from string to bool typeelif "--tester=TestUser" in item:config.tester = item.split(split_str)[1].strip()def get_cmdline_args(self):list = sys.argvreturn listdef read_config_from_cmdline(self,config):self.parse_settings_to_config(self.get_cmdline_args(),config)def __file_exist_check(self, file_path):if os.path.exists(file_path):return Trueelse:logger.error(f"File {file_path} does not exist.")return Falsedef read_case_from_list_file(self):test_list = "test_list.txt"# get path of test_list.txtfile_path = os.path.join(os.getcwd(), test_list)# print("os.path.abspath:", os.path.abspath(__file__))  #获取当前文件的绝对路径C:\code\USBTestAndroid\utils\api.py# print("os.getcwd()", os.getcwd())                     #获取调用该函数的项目路径C:\code\USBTestAndroid# print("file path :", file_path)case_list = []try:with open(file_path) as file_handle:lines = file_handle.readlines()for line in lines:case_list.append(line.strip())except FileNotFoundError as e:logger.error(f"file not found:{e}")except PermissionError as e:logger.error(f"No permission to read the file:{e}")except Exception as e:logger.error(f"file not found: {e}")return case_listdef config_file_status(self, file_path):"""check if config file is exist:return: True ,exist;False not exist"""return self.__file_exist_check(file_path)def read_config_from_file(self, file_path):config_list = []if self.config_file_status(file_path):try:with open(file_path) as file_handle:lines = file_handle.readlines()for line in lines:config_list.append(line.strip())except FileNotFoundError as e:logger.exception(f"file not found:{e}")except PermissionError as e:logger.exception(f"No permission to read the file:{e}")except Exception as e:logger.exception(f"file not found: {e}")return config_list   # config_list 正确else:logger.error("Config file is not exist....Please check again,Test Stop......")exit()def get_test_config(self, config):"""1. read config from config file2. check flag of test config . if true , read test config from config fileif false , read test config from cmdline:param config: Object of Class TestConfig"""split_str = "="config_list = self.read_config_from_file(CONFIG_FILE)run_from_cfg_file = ast.literal_eval(config_list[0].split(split_str)[1].strip())if run_from_cfg_file:logger.info("reading test config from config file ......")self.parse_settings_to_config(config_list, config)else:self.read_config_from_cmdline(config)logger.info("getting test config from cmdline ......")

下面的工作就是利用读取到的配置信息开始测试。

run_test.py:

    logger.info("Starting test execution...")config = TestConfig()functionApi.get_test_config(config)run_pytest(config)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88142.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平衡二叉树的删除操作

对于平衡二叉树的操作应对与考试只需要模拟出过程即可,且他的过程和插入的平衡方法一样,不一样的只是对于平衡因子的计算上。接下来我将给出方法①删除结点(方法同“二叉排序树”) ②一路向北找到最小不平衡子树,找不到…

Spark 4.0的 VariantType 类型优点以及使用分析

背景 本文基于Spark 4.0。 总结 对于半结构化的数据来说,我们一般会有两种方式进行存储: 第一种是存储为JSON String,这种可以保证Schema free,但是在使用的时候得解析为JSON,从而进行运算操作。 第二种是存储为Struct类型,这种虽…

17-C#封装,继承,多态与重载

C#封装继承多态 1. 2. 3.多态 public abstract class animal//抽象类 {public abstract void eat();//抽象方法 } public class cat : animal//继承 {public override void eat()//重写{messagebox.show("cat eat");} } public class dog: animal//继承 {public over…

恒创科技:香港站群服务器做seo站群优化效果如何

香港站群服务器做 SEO 站群优化效果如何?在当前搜索引擎优化竞争日益激烈的环境下,越来越多的企业开始关注站群策略这一高效的 SEO 手段。作为亚洲重要的网络枢纽,香港站群服务器因其独特优势,正成为实施 SEO 站群优化的热门选择。本文将客观…

Linux-进程管理

Linux-进程管理Linux 进程管理1. 进程的含义2. 进程状态3. 进程工作模式4. 守护进程5. 进程查看命令5.1 ps 命令5.2 top 命令5.3 pstree 命令6. 终止进程的 kill 命令7. 前后台运行8. 暂停进程9. 进程文件系统 /proc10. 定时任务管理10.1 at 命令10.2 batch 命令10.3 cron 与 c…

OpenCV图像增强秘籍:高通滤波与特效艺术

> 在数字图像处理领域,边缘是图像最富信息的区域。掌握高通滤波技术,你就能让图像中的隐藏细节"跃然纸上",甚至创造惊艳的艺术效果。 ## 一、图像增强与高通滤波基础 ### 1.1 图像增强的核心目标 图像增强不是简单的美化,而是通过技术手段**突出重要特征*…

347. 前K个高频元素

题目: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 解题思路: 要返回出现频率前k高的元素,那么我们首…

C++面试冲刺笔记1:虚函数的基本工作原理

C面试冲刺笔记1:虚函数的基本工作原理 前言 ​ 笔者最近开始投简历,出于应对之后快速的面试流程需求,这里准备的是将常见的C八股文进行总结,从而方便自己进行学习,检查和评估。 什么是虚函数 ​ 虚函数,本质…

Spring Boot 事务失效问题详解:原因、场景与解决方案

在 Spring Boot 开发中,事务管理是保证数据一致性和完整性的核心机制。然而,许多开发者在使用 Transactional 注解时,可能会遇到事务失效的问题,导致数据异常或业务逻辑错误。本文将深入分析 Spring Boot 中事务失效的常见原因&am…

Python-文件操作-StringIO和BytesIO-路径操作-shutil模块-csv,ini序列化和反序列化-argparse使用-学习笔记

序 欠4年前的一份学习笔记,献给今后的自己。 文件操作 冯诺依曼体系架构CPU由运算器和控制器组成 运算器,完成各种算数运算、逻辑运算、数据传输等数据加工处理 。 控制器,控制程序的执行 存储器,用于记忆程序和数据,例…

LLM的表征做减法的是什么,自然语言是一个矩阵,怎么进行减法的

LLM的表征做减法的是什么,自然语言是一个矩阵,怎么进行减法的 有个假设:就是最后一个词语融合了前面词语的信息 减法操作主要用于提取模型内部表征中的"诚实性"概念向量。具体来说,这是通过对比诚实和不诚实场景下的模型隐藏状态实现的。 import torch from t…

Java创建型模式---单例模式

单例模式基础概念单例模式是一种创建型设计模式,其核心思想是确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。在 Java 中实现单例模式主要有以下关键点:私有构造函数 - 防止外部通过new关键字创建实例静态实例变量 - 类内部持有…

详解Kafka重平衡机制详解

Kafka 的重平衡机制(Rebalance)是确保消费者组内成员动态变化(如新成员加入、现有成员退出或崩溃、订阅主题分区数变化)时,分区所有权能合理、公平地重新分配的核心机制。其目标是保证所有分区都有消费者处理&#xff…

代码详细注释:文件IO在用户管理系统中的应用实践:C语言实现用户名查重与密码确认与支持日志记录的终端用户认证解决方案的注册登录系统

代码/* 作业增强版注册登录系统 - 带日志和安全性增强功能 */ #include <stdio.h> // 标准输入输出函数(printf, scanf等) #include <stdlib.h> // 标准库函数(exit, malloc等) #include <string.h> // 字符串处理函数(strcmp, strcspn等) #inc…

Go与JS无缝协作:Goja引擎实战之错误处理最佳实践

引言&#xff1a;当Go邂逅JavaScript 在现代软件开发中&#xff0c;跨语言协作已成为提升效率的关键。想象一下&#xff1a;用Go的高性能处理核心逻辑&#xff0c;同时用JavaScript的灵活性实现动态规则——这不再是梦想。Goja&#xff0c;这个纯Go语言实现的JavaScript引擎&am…

继承与多态:面向对象编程的两大支柱

引言&#xff1a;为什么必须掌握继承与多态&#xff1f; 在Java开发中&#xff0c;继承与多态是构建可扩展、易维护系统的基石&#xff1a; 继承&#xff1a;实现代码复用&#xff0c;建立清晰的类层次结构多态&#xff1a;提升代码灵活性&#xff0c;实现"编写一次&#…

2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--上篇

前言 我们在学习Flutter开发的过程中&#xff0c;永远都跳不过去的一个问题就是如何在MAC下开发并打包Flutter工程项目&#xff0c;但MAC开发首先要解决的问题就是我们一般技术人员的电脑都是WINDOWS操作系统&#xff0c;专门配置一台MAC的话成本又是不得不考虑的因素&#xf…

250708-Svelte项目从Debian迁移到无法联网的RHEL全流程指南

&#x1f4cc; 背景 在 Debian 上使用以下命令创建了一个 Svelte 项目&#xff1a; npm install -g sv npx sv create my-svelte-demo cd my-svelte-demo npm install npm run dev现在需要将该项目迁移到一台 无法联网的 RHEL 9.4 服务器 上运行&#xff0c;出现如下报错&…

力扣 hot100 Day39

118. 杨辉三角 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 class Solution { public:vector<vector<int>> generate(int numRows) {vector<vector<int>> res(numRows);for (int i 0; i < numRows; i) {res[i].resi…

HuggingFists: 无代码处理复杂PDF

有过使用LLM搭建RAG或其它类知识系统的朋友一定会对文档数据的复杂多样性有着深刻的理解。各行各业的磁盘中都沉睡了数年到数十年的各类文档信息&#xff0c;包括&#xff1a;Doc、Docx、PPT、PDF、XLS、PNG、JPEG等各类格式。利用LLM激活这些数据价值的首要工作就是能够正确的…