PO模式登录测试

项目实践

登陆项目测试

get_driver

import page
from selenium import webdriver


class GetDriver:
    driver = None

    @classmethod
    def get_driver(cls):
        if cls.driver is None:
            cls.driver = webdriver.Edge()
            cls.driver.maximize_window()
            cls.driver.get(page.url)

        return cls.driver

    @classmethod
    def quit_driver(cls):
        if cls.driver:
            cls.driver.quit()
            cls.driver = None

get_logger

import logging.handlers


class GetLogger:
    logger = None

    @classmethod
    def 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 time

from base.get_logger import GetLogger


log = GetLogger().get_logger()


class Base:
    def __init__(self, driver):
        log.info("正在初始化driver{}".format(driver))
        self.driver = driver

    def 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 True
        except:
            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 page


class 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 json


def 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/" + filename
    with open(filepath, "r", encoding="utf-8")as f:
        return f.readlines()


业务层

# 导包
import unittest
from time import sleep

from 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 GetLogger


log = 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

    @classmethod
    def setUpClass(cls):
        try:
            # 实例化 获取页面对象 PageLogin
            cls.login = PageLogin(GetDriver().get_driver())
            # 点击登录连接
            cls.login.page_click_login_link()
        except Exception as e:
            log.error(e)

    # tearDown
    @classmethod
    def 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 unittest

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于批量采集1688商品主图及链接的方式:软件采集/1688官方API接口数据采集

关于批量采集,我们通常用到的是软件 采集,或者通过1688官方API数据采集的形式:用户输入一组1688商品ID,一行一个,流程会自动逐个打开对应的1688商品详情页,采集主图的所有链接。 结果保存为表格的一行&…

Linux运维之管道符、重定向与环境变量

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 目录 一、输入输出重定向 二、管道命令符 三、命令行的通配符 四、常用的转义字符 五、重要的环境变量 致谢 一、输入输出重定向 输入重定向是…

【Python+微信小程序】学生考勤签到系统(已开源)

1. 简介 😝 这个项目是一款基于微信小程序和Flask框架开发的应用,旨在帮助学校管理学生的考勤和课程信息。系统通过集成数据库管理、API开发以及前后端交互,实现了便捷的学生考勤记录、课程表管理和教师交互功能。其主要特点包括&#xff1a…

程序化交易广告及其应用

什么是程序化交易广告? 程序化交易广告是以实时竞价技术即RTB(real-time bidding)为核心的广告交易方式。说到这里,你可能会有疑问:像百度搜索关键词广告还有百度网盟的广告,不也是CPC实时竞价的吗&#x…

Python学习笔记22:进阶篇(十一)常见标准库使用之访问互联网功能urllib模块的学习使用,requests库和aiohttp库了解

前言 本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。 根据模块知识,一次讲解单个或者多个模块的内容。 教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html 互联网访…

【基于R语言群体遗传学】-5-扩展到两个以上等位基因及多基因位点

我们现在继续对于群体遗传学进行统计建模,书接上回,我们讨论了孤雌生殖的物种违反哈代温伯格遗传比例的例子,那我们现在来看多于两个等位基因的情况的计算。 如果没有看过之前文章的同学,可以先去看一下之前的文章: …

1.2 ROS2安装

1.2.1 安装ROS2 整体而言,ROS2的安装步骤不算复杂,大致步骤如下: 准备1:设置语言环境;准备2:启动Ubuntu universe存储库;设置软件源;安装ROS2;配置环境。 请注意&…

多模态图像生成的突破:Image Anything一种无需训练的智能框架

多模态图像生成是内容创作领域的热点技术,尤其在媒体、艺术和元宇宙等领域。该技术旨在模拟人类的想象力,将视觉、文本和音频等多种模态属性相关联,以生成图像。早期的方法主要侧重于单一模态输入的图像生成,例如基于图像、文本或…

240703_昇思学习打卡-Day15-K近邻算法实现红酒聚类

KNN(K近邻)算法实现红酒聚类 K近邻算法,是有监督学习中的分类算法,可以用于分类和回归,本篇主要讲解其在分类上的用途。 文章目录 KNN(K近邻)算法实现红酒聚类算法原理数据下载数据读取与处理模型构建--计算距离模型预测 算法原理 KNN算法虽…

Mac单机游戏推荐:星际争霸母巢之战 for Mac v1.16.1汉化版

星际争霸母巢之战 for Mac是一款深受玩家的即时战略游戏,延续了原版《星际争霸》的剧情,并加入了新的游戏单位、科技、地图样式、背景音乐及平衡性调整。《星际争霸》与其它的即时战略类型游戏。 下载地址:点击下载 与原作相同,《…

一图胜千言|用Python搞定统计结果展示!

分享一份原创Python可视化教程:530张图形8000行代码,轻松搞定统计结果展示,部分如下, 每类图表包含详细代码详细代码注释,多达8000行代码,例如, 如何加入学习? 👇&#…

免费分享:2022年全国地铁站点数据(附下载方法)

数据简介 2022年全国地铁站点数据不仅反应我国城市交通网络的日益完善,也为城市规划、公共交通优化、商业布局、应急响应及智慧城市建设提供了宝贵的数据支持与参考,助力城市发展与居民生活质量的全面提升。 数据属性 数据名称:全国地铁站点…

Java同步包装器

通过 Collections.synchronizedList() 方法将一个普通的 ArrayList 包装成了线程安全的 List&#xff1a; import java.util.*;public class SynchronizedWrapperExample {public static void main(String[] args) {// 创建一个非线程安全的 ArrayListList<String> list…

python gdal 压缩栅格数据

1 压缩方法LZW 使用 LZW&#xff08;Lempel-Ziv-Welch&#xff09;&#xff0c;主要对图像数据压缩&#xff0c;可逆 2 代码 函数gdal_translate()&#xff1a;转换栅格的不同格式 我们使用的数据是GTiff格式的数据 GTiff – GeoTIFF File Format — GDAL documentation 参…

MySQL安装与环境配置

1.打开安装程序 2.默认配置&#xff0c;如下二三图 3.配置密码 4.等待安装完毕 5.检查 6.配置环境变量 7.从控制台登录检测

STM32F1+HAL库+FreeTOTS学习4——任务挂起与恢复

STM32F1HAL库FreeTOTS学习4——任务挂起与恢复 任务挂起和恢复的API介绍代码实现 上一期我们学习了FreeRTOS中任务创建的两种方法&#xff0c;这一期我们学习任务的挂起和恢复。 任务挂起和恢复的API介绍 在 &#xff1a;STM32F1HAL库FreeTOTS学习1——FreeRTOS入门 的学习中&…

苹果电脑虚拟机运行Windows Mac环境安装Win PD19虚拟机 parallels desktop19虚拟机安装教程免费密钥激活

在如今多元的数字时代&#xff0c;我们经常需要在不同的操作系统环境下进行工作和学习。而对于 Mac 用户来说&#xff0c;有时候需要在自己的电脑上安装 Windows 操作系统&#xff0c;以体验更多软件及功能&#xff0c;而在 Mac 安装 Windows 虚拟机是常用的一种操作。下面就来…

Python28-5 k-means算法

k-means 算法介绍 k-means 算法是一种经典的聚类算法&#xff0c;其目的是将数据集分成 ( k ) 个不同的簇&#xff0c;每个簇内的数据点尽可能接近。算法的基本思想是通过反复迭代优化簇中心的位置&#xff0c;使得每个簇内的点与簇中心的距离之和最小。k-means 算法的具体步骤…

【FFmpeg】avformat_find_stream_info函数

【FFmpeg】avformat_find_stream_info 1.avformat_find_stream_info1.1 初始化解析器&#xff08;av_parser_init&#xff09;1.2 查找探测解码器&#xff08;find_probe_decoder&#xff09;1.3 尝试打开解码器&#xff08;avcodec_open2&#xff09;1.4 读取帧&#xff08;re…

嵌入式Linux之Uboot简介和移植

uboot简介 uboot 的全称是 Universal Boot Loader&#xff0c;uboot 是一个遵循 GPL 协议的开源软件&#xff0c;uboot是一个裸机代码&#xff0c;可以看作是一个裸机综合例程。现在的 uboot 已经支持液晶屏、网络、USB 等高级功能。 也就是说&#xff0c;可以在没有系统的情况…