自动化软件测试的基本流程

一、自动化测试的准备

1.1  了解测试系统

        首先对于需要测试的系统我们需要按照软件需求说明书明确软件功能。这里以智慧养老系统作为案例进行测试,先让我们看看该系统的登录界面和用户管理界面。

登录界面:

登录成功默认界面:

用户管理界面:

1.2  绘制脑图

        使用脑图绘制出系统重每一个功能需要测试的流程和内容(绘制工具建议使用Xmid),这里没有写出完整系统的功能,只绘制了登录、注册用户以及用户管理界面的功能。

1.3  创建python项目

        利用 PyCharm 创建python项目,创建完毕后一定检查设置中解释器里是否有selenium和webdrivermanger 两个插件。我这肯定是有的,这两玩意装起来非常非常的费劲,要是不会安装的话可以私信给我。

 二、自动化测试代码编写

2.1 分组        

        明确了自己需要测试的几个功能,我们可以以他们为标题创建python文件,例如关于登录界面的测试就叫 Login.py ,关于注册的测试就叫 Register.py , 关于用户管理的测试叫UserMange.py,并且在每一个页面中编写相关的测试用例。

        但是每一个python文件都需要利用webDriverMange下载相关的浏览器驱动并且以特定的方式打开特定浏览器的特定页面。因此如果每一次都在文件中创建一次浏览器驱动对象是非常麻烦且浪费空间的,我们可以统一创建一个浏览器驱动对象,并且以单例模式的方式提供给整个项目中的所有测试文件使用。在这里我们创建Utils.py 文件用于存放所有文件需要使用到的工具,例如浏览器驱动对象、屏幕截图方法等等。

        并且在这里我们将 utils 文件放入common包中,将其他页面和功能的测试放入tests包中。为什么要将这些文件分别放到一个包呢,因为需要方别被别人导入和使用,文件夹是没有办法被其他文件导入和使用的(包中有__init__.py 文件 文件夹是没有的)

2.2 Utils.py 测试文件配制

        在Driver类中创建一个浏览器对象并且使用单例模式进行实例化,使得所有的文件只能使用OSDriver 这个对象实例化处的Driver类型的浏览器启动对象。

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager


#创建浏览器驱动对象
class Driver:
    driver = ""
    def __init__(self):
        options = webdriver.ChromeOptions()
        self.driver = webdriver.Chrome(service=ChromeDriverManager().install(), options=options)
#此为单例模式的使用,使得其他文件只能使用这一个创建好的对象
OSDriver = Driver()

2.3 Login.py 登录页测试

        在这里我们根据脑图编写代码测试了选择正确的身份,正确输入用户名和密码以及选择错误的身份输入用户名密码的情况。代码如下所示。这些代码无非就是选中输入框进行自动输入以及点击等操作,并没有什么难度,唯一要注意的是,在一个函数内写完测试用例后,不要再函数里进行浏览器驱动对象的退出,这一步操作会导致其他的函数执行失败。

        在输入错误的测试用例中,这里添加了一个屏幕截图的操作,这一步操作可以将被截屏的照片存放在当天日期的文件夹中,并且文件名为调用截屏的函数名+日期时间。为了完成这一步操作我们首先需要在Utils文件中添加屏幕截图的函数getScreenShot。

# 此为创建屏幕截图的函数
    def getScreenShot(self):
        #文件名称为:../images/当天的日期/当天的日期以及时间.png
        dirName = datetime.datetime.now().strftime("%Y-%m-%d")
        #判断当日存放的照片路径(dirName)是否存在,如果不存在则创建一个
        if not os.path.exists("../images/"+dirName):
            os.makedirs("../images/"+dirName)
        #创建错误照片的文件名(当天的日期以及时间.png)
        # sys._getframe().f_back.f_code.co_name 能够获取到调用该方法的方法名
        filename = sys._getframe().f_back.f_code.co_name + "-" +datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"
        self.driver.save_screenshot("../images/"+dirName+"/"+filename)

 添加完毕后可以在 Login.py 文件中直接使用屏幕截图函数。

import time

from selenium.webdriver.common.by import By

from common.Utils import OSDriver


class Login:
    url= ""
    driver = ""
    def __init__(self):
        self.url = "http://localhost:8081/login"
        #将Utils中的浏览器驱动对象导入进来
        self.driver = OSDriver.driver
        #利用驱动对象将url指定的地址打开
        self.driver.get(self.url)

    #成功登陆的测试用例
    def LoginSuccess1(self):
        #输入正确的管理员账号密码
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("admin")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("123")
        #选择管理员身份
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > div:nth-child(6) > div > div > input").send_keys("管理员")
        #提交登录请求
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > input[type=submit]:nth-child(8)").click()
        #检查是否登录成功
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > ul > li:nth-child(2) > a")
        self.driver.quit()

    def LoginSuccess2(self):
        # 输入正确的用户账号密码
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("hjy")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("123456")
        # 选择用户身份
        # time.sleep(2)
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > div:nth-child(6) > div > div > input").click()
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > div:nth-child(6) > div > dl > dd:nth-child(2)").click()
        # 提交登录请求
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input[type=submit]:nth-child(8)").click()
        # 检查是否登录成功
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container > ul > li:nth-child(2) > a")
        self.driver.quit()
    #异常登录的测试用例
    def LoginFail1(self):
        #选择管理员账号,输入账号:admin 输入密码:1
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("admin")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("1")
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > input[type=submit]:nth-child(8)").click()
        #检查是否有文本提示信息
        ErroTest = self.driver.find_element(By.CSS_SELECTOR,"body > div > form > span")
        assert ErroTest.text == "请确定账户信息是否正确!"
        self.driver.quit()

    def LoginFail2(self):
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("hjy")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("1")
        #选择用户身份
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > div:nth-child(6) > div > div > input").click()
        self.driver.find_element(By.CSS_SELECTOR,"body > div > form > div:nth-child(6) > div > dl > dd:nth-child(2)").click()
       #点击登录
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input[type=submit]:nth-child(8)").click()
        ErroTest = self.driver.find_element(By.CSS_SELECTOR, "body > div > form > span")
        #检查结果是否符合预期
        OSDriver.getScreenShot()
        assert ErroTest.text == "请确定账户信息是否正确!"
        self.driver.quit()

Login().LoginFail2()

2.4 Register.py 注册页测试

        依然是根据脑图挑选了几个测试用例进行测试。

from selenium.webdriver.common.by import By

from common.Utils import OSDriver


class Register:
    url=""
    driver = ""
    def __init__(self):
        self.url = "http://localhost:8081/register"
        self.driver = OSDriver.driver
        self.driver.get(self.url)

    def RegisterSucess1(self):
        #输入正确的用户名  用户名:xuwei    密码:123456
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("xuwei")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(6)").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input[type=submit]:nth-child(8)")
        self.driver.back()

    def RegisterFail1(self):
        #输入正确的账号并且输入小于6位不为空格的密码  输入账号:test1  输入密码:11111
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("test1")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("11111")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(6)").send_keys("11111")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input[type=submit]:nth-child(8)").click()
        #检查提示文本是否出现
        ErrTest = self.driver.find_element(By.CSS_SELECTOR,"body > div > form > span")
        if not ErrTest.text == "密码必须大约6位!":
            OSDriver.getScreenShot()
        assert ErrTest.text == "密码必须大约6位!"
        self.driver.back()

    def RegisterFail2(self):
        #输入正确的账号并且输入的密码为6个空格  输入账号:test2 输入密码:******(*在此处代表空格)
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(2)").send_keys("admin")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(4)").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input:nth-child(6)").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR, "body > div > form > input[type=submit]:nth-child(8)").click()
        #检查提示文本是否出现:用户名重复,请重新输入!
        ErrTest = self.driver.find_element(By.CSS_SELECTOR,"body > div > form > span")
        if not ErrTest.text == "用户名重复,请重新输入!":
            OSDriver.getScreenShot()
        assert ErrTest.text == "用户名重复,请重新输入!"
        self.driver.back()

Register().RegisterSucess1()
Register().RegisterFail1()
Register().RegisterFail2()

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

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

相关文章

前端力扣刷题 | 6:hot100之 矩阵

73. 矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 法一: var setZeroes function(matrix) {let setX new Set(); // 用于存储需要置零的行索引let setY new Set(); //…

SLAM技术栈 ——《视觉SLAM十四讲》学习笔记(一)

《视觉SLAM十四讲》学习笔记(一) 第2讲 初识SLAM习题部分 第3讲 三维空间刚体运动3.1 左手系与右手系3.2 齐次坐标3.3 旋转矩阵与变换矩阵3.4 正交群与欧式群3.5 旋转向量与欧拉角3.6 实践Eigen线性代数库3.6.1 QR分解(QR decomposition) 3.7 四元数到其…

自动驾驶---两轮自行车的自主导航

1 背景 无人驾驶汽车最早出现在DARPA的比赛中,从那个时刻开始,逐渐引起全球学者的注意,于是从上个世纪开始各大高校院所开始了无人汽车的研发。直到这两年,无人驾驶汽车才开始走进寻常百姓家,虽然目前市面上的乘用车还…

Spring Boot 2 快速教程:WebFlux处理流程(五)

WebFlux请求处理流程 下面是spring mvc的请求处理流程 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找) 匹配条件包括…

优选算法的灵动之章:双指针专题(一)

个人主页:手握风云 专栏:算法 一、双指针算法思想 双指针算法主要用于处理数组、链表等线性数据结构中的问题。它通过设置两个指针,在数据结构上进行遍历和操作,从而实现高效解决问题。 二、算法题精讲 2.1. 查找总价格为目标值…

Intel 与 Yocto 项目的深度融合:全面解析与平台对比

在嵌入式 Linux 领域,Yocto 项目已成为构建定制化 Linux 发行版的事实标准,广泛应用于不同架构的 SoC 平台。Intel 作为 x86 架构的领导者,在 Yocto 生态中投入了大量资源,为其嵌入式处理器、FPGA 和 AI 加速硬件提供了完整的支持…

算法刷题Day29:BM67 不同路径的数目(一)

题目链接 描述 解题思路: 二维dp数组初始化。 dp[i][0] 1, dp[0][j] 1 。因为到达第一行第一列的每个格子只能有一条路。状态转移 dp[i][j] dp[i-1][j] dp[i][j-1] 代码: class Solution: def uniquePaths(self , m: int, n: int) -> int: #…

98,【6】 buuctf web [ISITDTU 2019]EasyPHP

进入靶场 代码 <?php // 高亮显示当前 PHP 文件的源代码&#xff0c;通常用于调试或展示代码&#xff0c;方便用户查看代码逻辑 highlight_file(__FILE__);// 从 GET 请求中获取名为 _ 的参数值&#xff0c;并赋值给变量 $_ // 符号用于抑制可能出现的错误信息&#xff…

C++中常用的十大排序方法之4——希尔排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之4——希尔排序的相…

字节iOS面试经验分享:HTTP与网络编程

字节iOS面试经验分享&#xff1a;HTTP与网络编程 &#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 目录 字节iOS面试经验分享&#xff1a;HTT…

音视频入门基础:RTP专题(7)——RTP协议简介

一、引言 本文对RTP协议进行简介。在简介之前&#xff0c;请各位先下载RTP的官方文档《RFC 3550》和《RFC 3551》。《RFC 3550》总共有89页&#xff0c;《RFC 3551》总共有44页。本文下面所说的“页数”是指在pdf阅读器中显示的页数&#xff1a; 二、RTP协议简介 根据《RFC 35…

SQLGlot:用SQLGlot解析SQL

几十年来&#xff0c;结构化查询语言&#xff08;SQL&#xff09;一直是与数据库交互的实际语言。在一段时间内&#xff0c;不同的数据库在支持通用SQL语法的同时演变出了不同的SQL风格&#xff0c;也就是方言。这可能是SQL被广泛采用和流行的原因之一。 SQL解析是解构SQL查询…

Java 大视界 -- Java 大数据在智能电网中的应用与发展趋势(71)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

想表示消息返回值为Customer集合

道奈特(240***10) 14:34:55 EA中序列图。我想表示消息返回值为 Customer 集合。目前只有一个Customer实体类&#xff0c;我需要另外新建一个CustomerList 类吗&#xff1f; 潘加宇(35***47) 17:01:26 不需要。如果是分析&#xff0c;在类的操作中&#xff0c;定义一个参数&…

01.双Android容器解决方案

目录 写在前面 一&#xff0c;容器 1.1 容器的原理 1.1.1 Namespace 1.1.2 Cgroups&#xff08;Control Groups&#xff09; 1.1.3 联合文件系统&#xff08;Union File System&#xff09; 1.2 容器的应用 1.2.1 微服务架构 1.2.2 持续集成和持续部署&#xff08;CI/…

【Elasticsearch】硬件资源优化

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

2025-工具集合整理

科技趋势 github-rank &#x1f577;️Github China/Global User Ranking, Global Warehouse Star Ranking (Github Action is automatically updated daily). 科技爱好者周刊 制图工具 D2 D2 A modern diagram scripting language that turns text to diagrams 文档帮助 …

二叉树--链式存储

1我们之前学了二叉树的顺序存储&#xff08;这种顺序存储的二叉树被称为堆&#xff09;&#xff0c;我们今天来学习一下二叉树的链式存储&#xff1a; 我们使用链表来表示一颗二叉树&#xff1a; ⽤链表来表⽰⼀棵⼆叉树&#xff0c;即⽤链来指⽰元素的逻辑关系。通常的⽅法是…

Java 23新特性

文章目录 Java 23新特性一、引言二、Markdown文档注释&#xff08;JEP 467&#xff09;示例 三、ZGC&#xff1a;默认的分代模式&#xff08;JEP 474&#xff09;1. 为什么要引入分代模式2. 使用分代模式的优势3. 如何启用分代模式 四、隐式声明的类和实例主方法&#xff08;JE…

【数据结构】_链表经典算法OJ:复杂链表的复制

目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;…