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)

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

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

相关文章

Java高风险漏洞与修复之——LDAP injection(LDAP注入)

LDAP注入介绍 LDAP注入是一种攻击技术,它可以利用应用程序中的安全漏洞对LDAP(轻量级目录访问协议)服务进行恶意查询或修改操作。当应用程序未能适当地清理用户的输入内容,将其嵌入到LDAP查询中时,就可能发生LDAP注入。攻击者通过注入未经授权的指令或条件来操纵查询结果…

【代码随想录训练营】【Day 66】【图论-3】| 卡码 101-104

【代码随想录训练营】【Day 66】【图论-3】| 卡码 101-104 需强化知识点 103,104 优化思路 题目 101. 孤岛的总面积 此处 area 多余 def dfs(grid, x, y, area):dirs [[0, 1], [0, -1], [1, 0], [-1, 0]]m, n len(grid), len(grid[0])area[0] 1grid[x][y] …

k8s学习笔记——k8s升级

前一段时间,由于搭建k8s集群的硬件设备故障,老化导致k8s需要重装。使用原来的kubeadm安装方式却发现装不了了。查了一下官方文档,说从v1.24版本之后,kubelet移除了容器引擎,容器及镜像管理将有第三方工具来接管&#x…

Vue.js有哪些优点和缺点

Vue.js 作为一个流行的前端框架,具有许多优点和一些潜在的缺点。以下是 Vue.js 的一些主要优点和缺点: 优点: 轻量级和灵活性:Vue.js 的核心库专注于视图层,这使得它非常轻量级(压缩后只有几十KB&#xff…

Web 反爬指南

本质上说,防抓的目的在于增加脚本或机器获取你网站内容的难度,而不要影响真实用户的使用或搜索引擎的收录 不幸的是这挺难的,你需要在防抓和降低真实用户以及搜索引擎的可访问性之间做一下权衡。 为了防爬(也称为网页抓取、屏幕…

智谱AI: ChatGLM API的使用

一、获取API 1、打开网址:智谱AI开放平台 注册账号登录 2、登录,查看API key (注册后赠送100万token,实名认证后多赠送400万, 有效期一个) 二、安装及调用 安装质谱SDK pip install zhipuai调用方式 流式调用 from zhipuai import ZhipuA…

开放签电子签章,让签字有迹可循

开放签(企业版)V2.0.5版本上线后,系统支持一键查询电子文件的签署操作记录,支持一键生成详细的签署记录报告,详细请看下图: 1、操作记录详情: 从合同发起、填写、签署、撤销等环节全流程展示操…

【Linux从入门到放弃】探究进程如何退出以进程等待的前因后果

🧑‍💻作者: 情话0.0 📝专栏:《Linux从入门到放弃》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢! 进…

常见反爬及应对

一,特殊混淆的还原 1.1 还原 AAEncode 与 JJEncode AAEncode是一种JavaScript代码混淆算法,利用它,可以将代码转换成 颜文字 表示的JavaScript代码。 去掉代码最后的 (‘‘),这是函数的自调用,去除后就是函数的声明…

【CSharp】定义结构体并指定字段对齐

【CSharp】定义结构体并指定字段对齐 1.背景2.代码3.分析1.背景 在 C# 中可以通过 StructLayout 属性来定义结构体并指定字段对齐方式。 在 C# 中,内存对齐是指数据在内存中的排列方式,使用StructLayout 特性用于控制结构体的内存布局。其特性可以指定字段的内存排列顺序(例…

【揭秘】国内十大顶尖AI大模型,引领智能科技新纪元

大模型大模型通常指的是参数量非常大、数据量也非常大的深度学习模型。这些模型由数百万到数十亿甚至更多的参数组成,需要海量的数据和强大的计算资源进行训练和推理学习的模型。大模型设计的目的在于提高模型的表示能力和性能、应对复杂数据集和任务、提升泛化能力…

6、限界上下文:定义领域边界的利器

在DDD限界上下文:定义领域边界的利器领域建模和微服务建设过程中,会有很多项目参与者,包括领域专家、产品经理、项目经理、架构师、开发经理和测试经理等。对于同样的领域知识,不同的参与者可能会有不同的理解。而且有的时候同一个…

嵌入式学习——硬件(Linux系统在2440上的启动)——day57

1. Linux2.6系统在s3c2440上的启动过程分三个阶段 1.1 启动u-boot 1.2 启动Linux内核 1.3 挂载根文件系统 2. bootloader 2.1 定义 bootloader的本质是一个裸机程序,bootlood专门是为了能够正确地启动linux操作系 统,在系统初上电时需要对系统做一些…

BK145FRC10HSK、BK165FRC10HSK电液比例开环控制变量泵放大器

BK15FRC10HAK、BK35FRC10HAK、BK45FRC10HAK、BK55FRC10HAK、BK70FRC10HSK、BK80FRC10HSK、BK90FRC10HSK、BK100FRC10HSK、BK120FRC10HSK、BK145FRC10HSK、BK165FRC10HSK、BK180FRC10HSK电液比例开环控制柱塞泵主要是在传统的液压泵基础上,增加了电液比例控制先导阀。…

从零开始实现大语言模型(二):文本数据处理

1. 前言 神经网络不能直接处理自然语言文本,文本数据处理的核心是做tokenization,将自然语言文本分割成一系列tokens。 本文介绍tokenization的基本原理,OpenAI的GPT系列大语言模型使用的tokenization方法——字节对编码(BPE, byte pair en…

重采样(上采样或下采样)是什么?

重采样(Resampling)是在数据处理中常用的一种技术,主要用于处理数据集中的不平衡问题。具体来说,重采样可以分为上采样(Oversampling)和下采样(Undersampling),它们分别是…

【bug报错已解决】ERROR: Could not find a version that satisfies the requirement

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言一、问题描述1.1 报错示例1.2 报错分析 二、解决方法2.1 方法一2.2 方法二 三、总结 引言 有没有遇到过那种让人…

软件开发中常用环境你都知道哪些?

目录 本地环境(Local Environment,简称 LOCAL) 开发环境(Development Environment,简称 DEV) 测试环境(Testing Environment,简称 TEST) 集成测试环境(Sy…

墨烯的C语言技术栈-C语言基础-003

三.数据类型 1.char // 字符数据型 2.short // 短整型 3.int // 整型 4.long // 长整型 5.long long // 更长的整型 6.float // 单精度浮点数 7.double // 双精度浮点数 为什么写代码? 为了解决生活中的问题 购物,点餐,看电影 为什么有这么多类型呢? 因为说的话都是字符型…

CM-UNet: Hybrid CNN-Mamba UNet for Remote Sensing Image Semantic Segmentation

论文:CM-UNet: Hybrid :CNN-Mamba UNet for Remote Sensing Image Semantic Segmentation 代码:https://github.com/XiaoBuL/CM-UNet Abstrcat: 由于大规模图像尺寸和对象变化,当前基于 CNN 和 Transformer 的遥感图像语义分割方…