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

PO模式登录测试

项目实践

登陆项目测试

get_driver

import page
from selenium import webdriverclass GetDriver:driver = None@classmethoddef get_driver(cls):if cls.driver is None:cls.driver = webdriver.Edge()cls.driver.maximize_window()cls.driver.get(page.url)return cls.driver@classmethoddef quit_driver(cls):if cls.driver:cls.driver.quit()cls.driver = None

get_logger

import logging.handlersclass GetLogger:logger = None@classmethoddef get_logger(cls):if cls.logger is None:cls.logger = logging.getLogger()cls.logger.setLevel(logging.INFO)sh = logging.StreamHandler()th = logging.handlers.TimedRotatingFileHandler(filename="../log/login.log",when="midnight",interval=1,backupCount=3,encoding="utf-8")fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'fm = logging.Formatter(fmt)sh.setFormatter(fm)th.setFormatter(fm)cls.logger.addHandler(sh)cls.logger.addHandler(th)return cls.logger

base

from selenium.webdriver.support.wait import WebDriverWait
import timefrom base.get_logger import GetLoggerlog = GetLogger().get_logger()class Base:def __init__(self, driver):log.info("正在初始化driver{}".format(driver))self.driver = driverdef base_find_element(self, loc, timeout=30, poll=0.5):log.info("正在查找元素{}".format(loc))return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc))def base_click(self, loc):log.info("正在点击元素{}".format(loc))self.base_find_element(loc).click()def base_input(self, loc, value):log.info("正在给元素输入内容{}".format(loc))el = self.base_find_element(loc)# 清空log.info("正在给元素{}清空".format(loc))el.clear()# 输入log.info("正在给元素{}输入内容".format(loc))el.send_keys(value)def base_get_text(self, loc):# 注意:一定要返回元素的文本信息log.info("正在获取元素{}文本".format(loc))return self.base_find_element(loc).text# 截图def base_get_screen_shot(self):self.driver.get_screenshot_as_file("../image/{}.png".format(time.strftime("%Y_%m_%d %H_%M_%S")))# 封装判断元素是否存在def base_if_exist(self, loc):try:self.base_find_element(loc, timeout=2)log.info("元素{}存在".format(loc))return Trueexcept:log.info("元素{}不存在".format(loc))return False

__init__

from selenium.webdriver.common.by import By"""项目配置地址"""
url = "https://demo5.tp-shop.cn/""""以下为登录页面元素配置信息"""# 用户名
login_username = By.ID, "username"
# 密码
login_pwd = By.ID, "password"
# 验证码
login_verify_code = By.ID, "verify_code"
# 登录按钮
login_btn = By.CSS_SELECTOR, ".J-login-submit"
# 获取异常文本信息
login_err_info = By.CSS_SELECTOR, ".layui-layer-content"
# 点击异常提示框 按钮
login_err_btn_ok = By.CSS_SELECTOR, ".layui-layer-btn0"
# 安全退出
login_logout = By.PARTIAL_LINK_TEXT, "安全退出"# 登录链接
login_link = By.PARTIAL_LINK_TEXT, "登录"

page_login 继承Base

from base.base import Base
import pageclass PageLogin(Base):# 点击登录链接def page_click_login_link(self):self.base_click(page.login_link)# 输入用户名def page_input_username(self, username):self.base_input(page.login_username, username)# 输入密码def page_input_password(self, pwd):self.base_input(page.login_pwd, pwd)# 输入验证def page_input_verify_code(self, code):self.base_input(page.login_verify_code, code)# 点击登录按钮def page_click_login_btn(self):self.base_click(page.login_btn)# 获取异常提示信息def page_get_error_info(self):return self.base_get_text(page.login_err_info)# 点击异常信息框 确定def page_click_err_btn_ok(self):self.base_click(page.login_err_btn_ok)# 截图def page_get_img(self):self.base_get_screen_shot()# 点击 安全退出 --》退出使用def page_click_logout(self):self.base_click(page.login_logout)# 判断是否登录成功def page_is_login_success(self):return self.base_if_exist(page.login_logout)# 判断是否退出成功def page_is_logout_success(self):return self.base_if_exist(page.login_link)# 组合业务方法def page_login(self, username, pwd,code):self.page_input_username(username)self.page_input_password(pwd)self.page_input_verify_code(code)self.page_click_login_btn()

数据准备

json:

{"login_001":{"username":"138000011112","password":"123456","verify_code":"8888","expect_result":"账号不存在!","success": false},"login_002":{"username":"13800001111","password":"1234567","verify_code":"8888","expect_result":"密码错误!","success": false},"login_003":{"username":"","password":"123456","verify_code":"8888","expect_result":"用户名不能为空!","success": false},"login_004":{"username":"13800001111","password":"","verify_code":"8888","expect_result":"密码不能为空!","success": false},"login_005":{"username":"13800001111","password":"123456","verify_code":"","expect_result":"验证码不能为空!","success": false},"login_006":{"username":"13800001111","password":"123456","verify_code":"8888","expect_result":"安全退出","success": true}
}

txt:

138000011112,123456,8888,账号不存在!,false
13800001111,1234567,8888,密码错误!,false
,123456,8888,用户名不能为空!,false
13800001111,,8888,密码不能为空!,false
13800001111,123456,,验证码不能为空!,false
13800001111,123456,8888,安全退出,true

数据驱动方法

json:

# 导包
import jsondef read_json(filename):filepath = "../data/" + filename# 打开文件并调用 load方法with open(filepath, "r", encoding="utf-8")as f:return json.load(f)

txt:

def read_txt(filename):filepath = "../data/" + filenamewith open(filepath, "r", encoding="utf-8")as f:return f.readlines()

业务层

# 导包
import unittest
from time import sleepfrom base.get_driver import GetDriver
from page.page_login import PageLogin
from parameterized import parameterized
from tool.read_json import read_json
from tool.read_txt import read_txt
from base.get_logger import GetLoggerlog = GetLogger().get_logger()def get_data():arr = []for data in read_json("login.json").values():arr.append((data.get("username"),data.get("password"),data.get("verify_code"),data.get("expect_result"),data.get("success")))return arr  # 注意:必须进行return 返回# def get_data():
#     arr = []
#     for data in read_txt("login.txt"):
#         arr.append(tuple(data.strip().split(",")))
#     return arr# 新建测试类
class TestLogin(unittest.TestCase):login = None@classmethoddef setUpClass(cls):try:# 实例化 获取页面对象 PageLogincls.login = PageLogin(GetDriver().get_driver())# 点击登录连接cls.login.page_click_login_link()except Exception as e:log.error(e)# tearDown@classmethoddef tearDownClass(cls):sleep(3)# 关闭 driver驱动对象GetDriver().quit_driver()def tearDown(self):self.login.driver.refresh()# 登录测试方法@parameterized.expand(get_data())def test_login(self, username, pwd, code, expect_result, success):# 调用登录方法self.login.page_login(username, pwd, code)if success:try:# 判断安全退出是否存在self.assertTrue(self.login.page_is_login_success())# 点击退出self.login.page_click_logout()try:# 判断登录是否存在self.assertTrue(self.login.page_is_logout_success)except:# 截图self.login.page_get_img()# 点击登录连接self.login.page_click_login_link()except Exception as e:# 截图self.login.page_get_img()log.error(e)else:# 获取登录提示信息msg = self.login.page_get_error_info()try:# 断言self.assertEqual(msg, expect_result)except AssertionError:# 截图self.login.page_get_img()# 点击 确认框self.login.page_click_err_btn_ok()

生成测试报告 

from tool.HTMLTestRunner import HTMLTestRunner
import unittestsuite = unittest.defaultTestLoader.discover("./", "test_login.py")
# 网页要wb
with open("../report/report_html.html", "wb") as f:HTMLTestRunner(stream=f).run(suite)

相关文章:

PO模式登录测试

项目实践 登陆项目测试 get_driver import page from selenium import webdriverclass GetDriver:driver Noneclassmethoddef get_driver(cls):if cls.driver is None:cls.driver webdriver.Edge()cls.driver.maximize_window()cls.driver.get(page.url)return cls.drivercl…...

X86 +PC104+支持WinCE5.0,WinCE6.0,DOS,WinXP, QNX等操作系统,工业控制数据采集核心模块板卡定制

CPU 模块 是一款基于RDC 3306的SOM Express模块。RDC 3306这款X86架构的CPU是一款性能高、稳定性强的处理器。 它是一款灵活精巧的主板(尺寸为91.8mm68.6mm),可以灵活的运用于用户的底板,节约开发成本。模块的接插件使用插针形式…...

视频监控汇聚和融合平台的特点、功能、接入方式、应用场景

目录 一、产品概述 二、主要特点 1、多协议支持 2、高度集成与兼容性 3、高性能与可扩展性 4、智能化分析 5、安全可靠 三、功能概述 1. 视频接入与汇聚 2. 视频存储与回放 3. 实时监控与预警 4. 信息共享与联动 5. 远程管理与控制 四、接入方式 1、直接接入 2…...

实习总结 --- 其他业务

一. 回归测试:回归测试与测新是对应的,当需求准入交付测试的时候首先要进行的就是测新,也就是对新功能对测试,一般是在sim环境下测试的;当测新通过后才会进行回归测试,回归测试的目的是为了保证老功能的正确…...

2024年上半年典型网络攻击事件汇总

文章目录 前言一、Ivanti VPN 的0 Day攻击(2024年1月)二、微软公司高管账户泄露攻击(2024年1月)三、Change Healthcare网络攻击(2024年2月)四、ConnectWise ScreenConnect漏洞利用攻击(2024年2月)五、XZ Utils软件供应链攻击(2024年3月)六、AT&T数据泄露攻击(20…...

Ozon、美客多补单测评黑科技:打造无懈可击的自养号补单环境

不管哪个跨境平台的风控都会做升级,相对的补单技术也需要进行相应的做升级,风控升级后,自己养号补单需要注意以下技术问题,以确保补单的稳定性和安全性: 一、物理环境 1. 硬件参数伪装:平台已经开始通过I…...

ES报错:解决too_many_clauses: maxClauseCount is set to 1024 报错问题

解决too_many_clauses: maxClauseCount is set to 1024 报错问题 问题场景报错信息问题分析解决1. 优化查询2. 增加maxClauseCount3. 改用其他查询类型修改后的查询示例 问题场景 查询语句:查询clcNo分类号包含分类O的所有文档 {"match_phrase_prefix":…...

完全指南:在Linux上安装和精通Conda

前言 Conda是一个强大的包管理和环境管理工具,特别适用于数据科学和机器学习项目。本文将详细指导你在Linux系统上安装、配置和充分利用Conda的方法。 步骤一:下载和安装Conda 下载安装包: wget https://repo.anaconda.com/miniconda/Minic…...

# linux 系统中,使用 “ ll “ 命令报错 “ bash ll command not found “ 解决方法:

linux 系统中,使用 " ll " 命令报错 " bash ll command not found " 解决方法: 一、错误描述: 报错原因: 1、这个错误表明你尝试在 bash shell 中执行 ll 命令,但是系统找不到这个命令。ll 通常…...

吴恩达深度学习笔记:机器学习策略(2)(ML Strategy (2)) 2.3-2.4

目录 第三门课 结构化机器学习项目(Structuring Machine Learning Projects)第二周:机器学习策略(2)(ML Strategy (2))2.3 快速搭建你的第一个系统,并进行迭代(Build your first system quickly…...

【软件测试】快速定位bug,编写测试用例

作为一名测试人员如果连常见的系统问题都不知道如何分析,频繁将前端人员问题指派给后端人员,后端人员问题指派给前端人员,那么在团队里你在开发中的地位显而易见 ,口碑、升值、加薪那应该是你遥不可及的梦 但是作为测试人员来说&…...

升级springboot3

坑爹的发版流水线,管天管地,springboot2过了维护期,就催着我们升级。 导致必须上jdk17 记录一下升级需要处理的事情 先升级springboot和cloud,这里定下基调,其他的才好跟着升级 https://spring.io/projects/spring-b…...

视频编解码从H.264到H.266:浅析GB28181安防视频汇聚EasyCVR视频压缩技术

随着信息技术的飞速发展,视频编解码技术也在不断革新,以适应高清、超高清甚至8K视频时代的到来。视频编解码技术作为数字多媒体领域的核心技术之一,也在不断地演进和革新。从早期的H.261到现在的H.265、H.266,每一次技术的升级都极…...

vue项目访问 域名/index.html 空页面问题

很大可能是vue前端没做404页面,在路由不匹配时会跳转到空路由页面。 也可以把所有路由不匹配的网址全部跳转到域名首页。防止出现404或者页面错误。 如果使用docker nginx部署项目,配置文件上会有 try_files $uri $uri/ /index.html; 这段配置会尝试…...

区块链开发入门:基础概念与实施技术详解

区块链开发入门:基础概念与实施技术详解 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 引言 随着区块链技术的快速发展,它已经不再局…...

Rust破界:前端革新与Vite重构的深度透视(下)

Rust破界:前端革新与Vite重构的深度透视(下) 前端开发者:拥抱 Rust 的策略与时机技能树的扩展 结语:跨界融合的未来展望Vite 重构的深远意义 附录:进一步探索 Rust 的资源指南 前端开发者:拥抱 …...

Android 解决 “Module was compiled with an incompatible version of Kotlin“ 问题

解决 “Module was compiled with an incompatible version of Kotlin” 问题 在Android开发中,有时我们会遇到Kotlin版本不兼容的问题。具体来说,你可能会看到如下错误: D:/.gradle/caches/transforms-3/caf5371a15e0d6ffc362b4a5ece9cd49…...

linux nfs的使用

版权声明:来自百度AI,此处记录是方便日后查看,无任何商业用途 linux网络文件共享服务之nfs NFS(Network File System)是一种允许计算机用户或者操作系统通过网络以类似本地的方式访问文件的协议。以下是一个简单的NF…...

eclipse断点调试(用图说话)

eclipse断点调试(用图说话) debug方式启动项目,后端调试bug调试 前端代码调试,请参考浏览器断点调试(用图说话) 1、前端 选中一条数据,点击删除按钮 2、后端接口打断点 断点按钮 介绍 resum…...

vue的学习--day2

如有错误,烦请指正~ 目录 一、什么是单页面应用程序 二、使用工具:node.js 三、工具链 易错点 一、什么是单页面应用程序 多个组件(例如登录、注册等以vue结尾的都叫做组件)在一个页面显示,叫单页面应用…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

大数据学习(132)-HIve数据分析

​​​​🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言&#x1f4…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

管理学院权限管理系统开发总结

文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...