pom web 自动化测试框架分享
这是初版的 pom web 测试框架,目录如下同时部分代码也放在下面,详细代码可前往 github 查看,欢迎大家给出宝贵意见。
|--base
| base_page.py(封装方法)
|
|--config
| allure_config.py(测试报告配置)
|
|--data
| code(验证码)
| user.yaml(用户目录)
|
|--logs
| log(日志文件)
| log.py(日志模块)
|
|--page_object
| login_page.py(登陆页面元素及流程)
|
|--reports(测试报告存放处)
| allure-page
| report
|
|--screenshot
| err_screenhot(错误截图)
| screenshot.py(截图模块)
|
|--test_case
| conftest(fixture配置)
| test_login.py(登录测试用例)
|
|--utils
| util(公共方法,类似于验证码识别等)
| web_driver.py(driver配置)
|
|--run.py(测试框架运行模块)
base(封装方法)
class BasePage:def __init__(self, driver):self.driver = driverself.logger = Logs.get_logger()self.scr = Screenshot(driver)"""打开url"""def open_url(self, url: str):self.driver.maximize_window()self.logger.info('最大化窗口')self.driver.get(url)self.logger.info(f'打开网址:{url}')# self.driver.implicitly_wait(80)"""元素定位,元组形态,返回web_element对象"""def locator(self, loc: tuple) -> WebElement:try:# 显示等待直到元素可见并可交互return self.display_wait(loc)except NoSuchElementException:self.logger.error(f'元素{loc}未找到')self.scr.screenshot(loc)raiseexcept TimeoutException:self.logger.error(f'元素{loc}未在规定时间内变为可见')self.scr.screenshot(loc)raise
config(测试报告配置)
# 用户数据路径
user_data_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'user.yaml')# 测试用例路径
def case_path(path):return os.path.join(os.path.dirname(path), 'test_cases')# 测试报告路径
def report_path(path):return os.path.join(os.path.dirname(path), 'reports')# 执行 pytest 命令生成 Allure 报告配置
pytest_command = ["pytest","test_login.py", # 登陆测试"test_home.py", # 首页测试"test_search.py", # 搜索测试"--alluredir=../reports/report","--clean-alluredir"]
# 执行 Allure 命令生成并打开报告配置
allure_command = ["allure", "generate", "report", "--clean"]
# 打开allure报告
allure_open = ["allure", "open", "allure-report"]
logs(日志)
class Logs:LOG_DIRECTORY = os.path.join(os.path.dirname(__file__), 'log_file')LOG_FORMAT = '[%(asctime)s] %(levelname)s %(name)s(%(lineno)d): %(message)s'LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'LOG_LEVEL = logging.INFOBACKUP_COUNT = 0_logger = Nonedef __init_subclass__(cls, **kwargs):super().__init_subclass__(**kwargs)cls.ensure_log_directory()@classmethoddef ensure_log_directory(cls):if not os.path.exists(cls.LOG_DIRECTORY):os.makedirs(cls.LOG_DIRECTORY)@classmethoddef get_logger(cls):if cls._logger is None:try:cls.ensure_log_directory()log_path = os.path.join(cls.LOG_DIRECTORY, f'{time.strftime("%Y%m%d")}.log')file_handler = TimedRotatingFileHandler(log_path, when="midnight", interval=1,encoding='utf8', backupCount=cls.BACKUP_COUNT)formatter = logging.Formatter(cls.LOG_FORMAT, datefmt=cls.LOG_DATE_FORMAT)file_handler.setFormatter(formatter)cls._logger = logging.getLogger(cls.__name__)cls._logger.setLevel(cls.LOG_LEVEL)cls._logger.addHandler(file_handler) except Exception as e:raise RuntimeError(f"无法初始化类的记录器 '{cls.__name__}': {e}")return cls._logger
page_object(页面对象)
class LoginPage(BasePage):# 网址_url = 'http://baidu.com'# 账号_account = ('id', 'account')# 密码_password = ('id', 'PASSWORD')# 登录_login_button = ('id', 'login_button')def correct_login(self, username, password):with allure.step("打开登陆页面"):self.open_url(self._url)with allure.step(f"输入账号:{username}"):self.input(self._account, username)with allure.step(f"输入密码:{password}"):self.input(self._password, password)with allure.step("点击登陆"):self.click(self._login_button)
screenshot(截图)
class Screenshot:def __init__(self, driver):self._driver = driverself._screenshot_path = os.path.join(os.path.dirname(__file__), 'err_screenshot')self._ensure_screenshot_directory()self._logger = Logs.get_logger()def _ensure_screenshot_directory(self):try:if not os.path.exists(self._screenshot_path):os.makedirs(self._screenshot_path)except Exception as e:self._logger.error(f"创建屏幕截图目录时出错: {e}")def screenshot(self, error_name):date_time = datetime.now().strftime('%Y-%m-%d_%H.%M.%S')screenshot_name = f'{error_name}_{date_time}.png'screenshot_path = os.path.join(self._screenshot_path, screenshot_name)try:self._driver.get_screenshot_as_file(screenshot_path)with open(screenshot_path, 'rb') as image_file:image_data = image_file.read()allure.attach(image_data, name=screenshot_name, attachment_type=allure.attachment_type.PNG)self._logger.info(f"截图成功: {screenshot_path}")except FileNotFoundError as e:self._logger.error(f"保存截图时文件路径不存在: {e}")except Exception as e:self._logger.error(f"截取屏幕快照并保存时出错: {type(e).__name__}: {e}")
test_case(测试用例)
conftest
@pytest.fixture(scope="class")
def driver():with allure.step("webdriver初始化"):driver_instance = init_driver()try:yield driver_instancefinally:with allure.step("退出浏览器"):driver_instance.quit()
test_login.py
@allure.epic("xxx系统")
@allure.feature("首页登陆页面")
class TestLogin:@pytest.fixture(autouse=True)def setup(self, driver):self._lp = LoginPage(driver)@allure.title("正确账号登录")@allure.description("验证正确账号可以登录首页")@allure.severity(allure.severity_level.BLOCKER)@pytest.mark.parametrize("login_account", yaml.safe_load(open(user_data_path))['login_data'])def test_login(self, driver, login_account):try:self._lp.correct_login(login_account['CorrectAccount'], login_account['CorrectPassword'])except Exception as e:screenshot_taker = Screenshot(driver)screenshot_taker.screenshot(f"登陆出错")raise e
unitls
unil
未用到公共方法,暂未配置
web_driver
def init_driver():options = Options()# 可选配置项options.page_load_strategy = 'eager' # 页面加载策略,默认为'normal',可选'eager'和'none'。# options.add_argument('--headless') #无头模式options.add_argument('--disable-gpu') # 禁用gpuoptions.add_argument('--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, ''like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"') # 用户代理# options.add_argument('--incognito') # 隐身模式options.add_argument('--disable-infobars') # 禁用信息栏(浏览器正在被自动化工具控制)options.add_argument('--start-maximized') # 窗口最大化options.add_argument('--ignore-certificate-errors') # 忽略证书错误options.add_argument('--no-sandbox') # 禁用沙箱模式# 设置浏览器首选项prefs = {'download.prompt_for_download': False, # 下载文件时是否提示保存对话框'safebrowsing.enabled': True, # 是否启用安全浏览功能'credentials_enable_service': False, # 是否启用保存密码提示'profile.password_manager_enabled': False # 是否启用密码管理功能}options.add_experimental_option('prefs', prefs)driver = webdriver.Chrome(options=options)return driver
run(运行文件)
# 初始化日志配置
logger = Logs.get_logger()# 路径配置
BASE_DIR = os.path.dirname(__file__)
TEST_CASE_DIR = os.path.join(BASE_DIR, 'test_cases')
REPORT_DIR = os.path.join(BASE_DIR, 'reports')def main():try:# 执行 pytest 命令生成 Allure 报告logger.info("正在运行 pytest 以生成 Allure 报告...")subprocess.run(pytest_command, cwd=TEST_CASE_DIR, shell=True)# 执行 Allure 命令生成报告logger.info("正在生成 Allure 报告...")subprocess.run(allure_command, cwd=REPORT_DIR, shell=True)# 打开 Allure 报告logger.info("打开Allure报告...")subprocess.run(allure_open, cwd=REPORT_DIR, shell=True)except subprocess.CalledProcessError as e:logger.error(f"发生错误: {e}")exit(1)if __name__ == "__main__":main()
相关文章:
pom web 自动化测试框架分享
这是初版的 pom web 测试框架,目录如下同时部分代码也放在下面,详细代码可前往 github 查看,欢迎大家给出宝贵意见。 |--base | base_page.py(封装方法) | |--config | allure_config.py(测试报告配…...
一些以前使用的linux及shell命令,gnuplot脚本
tar tar -cvzf xxx.tar.gz * -c,--create 创建新的tar文件 -v,--verbose 列出每一步处理涉及的文件的信息,只用一个“v”时,仅列出文件名 使用两个“v”时,列出权限、所有者、大小、时间、文件名等信息 -z,…...
Django一分钟:DRF模型序列化器处理关联关系的示例与注意事项
DRF的ModelSerializer序列化器与Django的Model模型紧密映射,本文将通过简单的示例介绍几种处理关联关系的方法。 1. 创建模型和初始数据 创建模型 from django.db import modelsclass Product(models.Model):product_name models.CharField(max_length255)quant…...
Python爬虫selenium框架基本使用
一、安装导入 使用包管理器安装 pip3 install selenium 二、WebDriver工具 要使用这个工具我们需要保证安装了一个浏览器的驱动器。 Python的WebDriver是一个用于自动化Web浏览器操作的工具,它属于Selenium的一部分,特别是Selenium 2.0及以后版本中…...
sql 时间交集
任务(取时间交集) 前端输入开始时间和结束时间,通过sql筛选出活动开始时间和活动结束时间再开时时间和结束时间有交集的活动 想法: 前后一段时间内遇到了类似取交集的,从网上找到了两种写法,再结合GPT等…...
【深度学习】05-Rnn循环神经网络-01- 自然语言处理概述/词嵌入层/循环网络/文本生成案例精讲
循环神经网络(RNN)主要用于自然语言处理的。 循环神经网络(RNN)、卷积神经网络(CNN)和全连接神经网络(FCN)是三种常见的神经网络类型,各自擅长处理不同类型的数据。下面…...
基于JAVA+SpringBoot+Vue的电商平台的设计与实现
基于JAVASpringBootVue的电商平台的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接🍅…...
CSS盒模型-怪异盒模型笔记-思维导图-案例等
文章目录 一、盒模型(重点)二、怪异盒模型三、块级元素和行内元素区别汇总四、块级元素和行内元素的转换(显示方式)||元素的显示和隐藏五、思维导图六、笔记资料 一、盒模型(重点) 所有HTML元素可以看作盒子。 CSS盒模型本质上是…...
thinkphp6开发的通用网站系统源码
thinkphp6开发的通用网站系统源码。 基于ThinkPHP6框架开发的通用后台权限管理系统,底层采用国内最流行的ThinkPHP6框架, 支持内容管理、文章管理、用户管理、权限管理、角色管理等功能。 代码下载百度网盘...
Junit 5 - 理解Mockito,提高UT 覆盖率
前言 当我是1个3年初级程序员时, 我被面试者问到1个问题: 如何保证你的开发任务交付质量 当我是1个7年开发组长时, 我被面试者问到另1个问题:如何保证你的团队的代码质量, 减少rework。 又若干年后, 我才…...
微服务sentinel解析部署使用全流程
sentinel源码地址: 介绍 alibaba/Sentinel Wiki GitHub sentinel官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html Sprong Cloud alibaba Sentinel文档【小例子】 : Sentinel alibaba/spring-cloud-alibaba Wiki GitHub 目录 1、…...
YOLO11震撼发布!
非常高兴地向大家介绍 Ultralytics YOLO系列的新模型: YOLO11! YOLO11 在以往 YOLO 模型基础上带来了一系列强大的功能和优化,使其速度更快、更准确、用途更广泛。主要改进包括 增强了特征提取功能,从而可以更精确地捕捉细节以更…...
机器学习框架(含实例说明)
机器学习框架是用于开发和部署机器学习模型的软件库和工具集。它们提供了一系列的算法、工具和基础设施,帮助开发者更高效地构建、训练和部署机器学习模型。以下是一些主要的机器学习框架及其详细介绍: 1. TensorFlow TensorFlow 是由Google开发的开源…...
vue2与vue3知识点
1.vue2(optionsAPI)选项式API 2.vue3(composition API)响应式API vue3 setup 中this是未定义(undefined)vue3中已经开始弱化this vue2通过this可以拿到vue3setup定义得值和方法 setup语法糖 ref > …...
从源码中学习动态代理模式
动态代理模式 动态代理是 Java 反射(Reflection)API 提供的一种强大机制,它允许在运行时创建对象的代理实例,而不需要在编译时静态地创建。 Java 提供了两种主要的方式来实现动态代理: 基于接口的动态代理:…...
谷歌浏览器完美清除缓存
1.在页面上按下键盘的F12,打开控制台。 2.鼠标放到刷新图标上,点击鼠标右键,选择‘清空缓存并硬性重新加载’。 这样浏览器对网站页面的缓存就彻底被清理干净了。 目前支持该操作方式的浏览器有谷歌和Edge浏览器。 有的浏览器不支持该方式操…...
《如何高效学习》
有道云笔记 第一部分 整体性学习策略 结构 结构就像思想中的一座城市,有很多建筑物,建筑物之间有道路相连,有高大而重要的与其他建筑有上百条路相连,无关紧要的建筑只有少数泥泞的小道与外界相通。 建立良好的知识结构就是绘制…...
阿里云ACP认证考试题库
最近有好些同学,考完阿里云ACP了,再来跟我反馈:自己花700买的阿里云ACP题库,结果答案是错的! 或者考完后发现,买的阿里云ACP题库覆盖率只有50%! 为避免大家继续踩坑,给大家分享一个阿…...
学习经验分享【38】YOLOv11解读——最新YOLO版本
YOLO算法更新速度很快,已经出到V11版本,后续大家有想发论文或者搞项目可更新自己的baseline了。后续将改进YOLOv11算法,有需要的朋友可关注,我会持续进行更新。 YOLO11是Ultralytics YOLO系列实时目标检测器的最新迭代版本&#x…...
电商选品/分析| 亚马逊常见插件爬虫实战之-helium插件
说明 插件爬虫相当于二次爬虫,二次加工信息,因为大部分插件信息也是从正规网上去获取数据,这次列举helium插件爬虫案例,其他插件爬虫也是类似这个方式. 需求 1、⽤⾕歌浏览器,下载chrome extension:“Helium 10 2、登录helium10 3、打开 打开Amazo…...
遇到慢SQL、SQL报错,应如何快速定位问题 | OceanBase优化实践
在数据库的使用中,大家时常会遇到慢SQL,或执行出错的SQL。对于某些SQL问题,其错误原因显而易见,但也有不少情况难以直观判断。面对这类问题,我们应当如何应对?如何准确识别SQL错误的根源?是否需…...
postgresql僵尸进程的处理思路
简介 僵尸进程(zombie process)是指一个已经终止但仍然在进程表中保留条目的进程。正常情况下,当一个进程完成执行并退出时,操作系统会通过父进程调用的wait()或waitpid()系统调用来收集该子进程的退出状态。如果父进程未及时调用…...
Springboot 练习
Springboot练习——分页查询 Emp类 package com.wzb.pojo20240930;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.time.LocalDate; import java.time.LocalDateTime;Data NoArgsConstructor AllArgsConstructor public…...
ISA-95制造业中企业和控制系统的集成的国际标准-(3)
ISA-95 文章目录 ISA-95ISA-95设备对象模型一、设备对象模型是什么?二、设备对象模型常见组织 ISA-95设备对象模型 ISA-95 标准中的设备对象模型侧重于表示制造和生产过程中使用的物理和逻辑设备及资源。 一、设备对象模型是什么? 设备对象模型提供了…...
MATLAB中图形导出功能的详细使用指南
在MATLAB中,图形的导出是一个常见的需求,无论是为了报告、演示还是进一步的分析。MATLAB提供了多种方式来导出图形,包括使用图形用户界面(GUI)的工具,以及通过编程方式使用特定的函数。本文将详细介绍如何在MATLAB中导出图形&…...
助农小程序|助农扶贫系统|基于java的助农扶贫系统小程序设计与实现(源码+数据库+文档)
助农扶贫系统小程序 目录 基于java的助农扶贫系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 5.1.1 农户管理 5.1.2 用户管理 5.1.3 订单统计 5.2.1 商品信息管理 5.3.1 商品信息 5.3.2 订单信息 5.3.3 商品评价 5.3.4 商品退货 四、数据库设计 1、…...
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
一、本地上传 概念:将前端上传的文件保存到自己的电脑 作用:前端上传的文件到后端,后端存储的是一个临时文件,方法执行完毕会消失,把临时文件存储到本地硬盘中。 1、导入文件上传的依赖 <dependency><grou…...
git clone或repo init 时报错:fatal: 协议错误:错误的行长度 xxx
执行repo init或git clone时报错:protocol error: bad line length 或协议错误:错误的行长度 系统版本:Ubuntu20.04 repo version v2.47 repo launcher version 2.45 git version 2.25.1 报错信息 fatal: 协议错误:错误的行长度 948 fatal: 远端意外挂断了 repo: err…...
SpringBoot2(Spring Boot 的Web开发 springMVC 请求处理 参数绑定 常用注解 数据传递 文件上传)
SpringBoot2(Spring Boot 的Web开发 springMVC 请求处理 参数绑定 常用注解 数据传递 文件上传) 一、Spring Boot的Web开发 1.静态资源映射规则 总结:只要静态资源放在类路径下: called /static (or /public or /resources or …...
成都网安周暨CCS2024 | 大模型安全与产业应用创新研讨活动成功举办
9月11日-12日,作为2024年国家网络安全宣传周成都系列活动的重磅活动之一,CCS 2024成都网络安全系列活动在成都举行。“大模型安全与产业应用创新研讨活动”同期举办,本场活动由百度安全、成都无糖信息联合承办,特邀云安全联盟CSA大…...
专业建设外贸网站制作江门/站长之家ppt模板
-- Start 在上一篇中,我们学会了如何创建节点以及如何保存数据到节点中,那么什么是节点呢?其实节点就像文件一样,是用来保存数据的,只不过在 ZooKeeper 中,我们把它称之为节点。如果有成千上万个节点&…...
行业网站导航/seo百度关键词优化
说明:点击下方论文链接可跳转到 微信论文解读页面 隐函数三维重建 Implicit Functions in Feature Space for 3D Shape Reconstruction and Completion Dynamic Neural Radiance Fields for Monocular 4D Facial Avatar Reconstruction Neural Body: Implicit …...
个体户 做网站/网站如何快速被百度收录
Yii的webservice是强大的,但是官方文档太垃圾,Api看了和没看一样,百度google的搜索提供不了任何帮助。所以我一定要记录下来,好让后来者不再浪费时间探索。首先,跟着官方文档一步步走,你肯定可以写出你的we…...
网站开发常去的论坛/汕头百度seo公司
任务1——搭一个框架 用const定义全局的常变量password,作为银行卡的密码。 判断输入的密码是否正确,如果不正确,提示,否则,继续下面的工作。 用switch多分支完成显示。 /**Copyright (c) 2014,烟台大学计算机学院*All…...
优跃达官网网站建设项目/爱站网排行榜
3-1、标识符。为什么python 中不需要变量名和变量类型声明? python语言是动态的、强类型语言,一言以蔽之! 动态编译语言特点: ◆不用事先声明类型,随时赋值为其他类型 ◆编译时不知道是什么类型,很难…...
网站建设包含以下哪些建设阶段/福建seo顾问
总线是计算机各种功能部件之间传送信息的公共通信干线,是由导线组成的传输线束。微机中有三种总线:数据总线、地址总线和控制总线;它们分别用来传输数据、数据地址和控制信号。本文操作环境:windows10系统、thinkpad t480电脑。相…...