python单元测试框架(继承、unittest参数化、断言、测试报告)

一、继承

继承能解决什么问题?

unittest每个模块都要用到前提条件以及清理,如果有上百个模块,我们要改域名和浏览器,就会工作量很大特别麻烦,这时我们可以用继承的思想只用改一次

我们可以将前提和清理提出来单独放到一个文件里,具体代码如下

from selenium import webdriver
import unittestclass Init(unittest.TestCase):@classmethoddef setUpClass(cls) -> None:cls.driver=webdriver.Chrome()cls.driver.maximize_window()cls.driver.get('http://www.baidu.com')cls.driver.implicitly_wait(30)@classmethoddef tearDownClass(cls) -> None:cls.driver.quit()

然后我们写测试用例的时候可以继承它,具体代码如下

from selenium import webdriver
import unittestfrom 单元测试框架.test.init import Init
class BaiduTest(Init):def test_baidu_title(self):'''百度测试:验证百度首页的title'''# assert self.driver.title=='百度一下,你就知道'self.assertEqual(self.driver.title,'百度一下,你就知道')def test_baidu_url(self):'''百度测试:验证百度首页的url'''assert self.driver.current_url=='https://www.baidu.com/'def test_baidu_video(self):'''百度测试:验证点击视频后跳转到视频的页面'''nowhandler=self.driver.current_window_handleself.driver.find_element_by_link_text('视频').click()allhandlers=self.driver.window_handlesfor handler in allhandlers:if handler!=nowhandler:self.driver.switch_to.window(handler)self.assertTrue(self.driver.current_url,'https://haokan.baidu.com/?sfrom=baidu-top')self.driver.close()self.driver.switch_to.window(nowhandler)def test_baidu_map(self):'''百度测试:验证点击地图后跳转到地图的页面'''nowhandler=self.driver.current_window_handleself.driver.find_element_by_link_text('地图').click()allhandlers=self.driver.window_handlesfor handler in allhandlers:if handler!=nowhandler:self.driver.switch_to.window(handler)self.assertTrue(self.driver.current_url.startswith('https://map.baidu'))self.driver.close()self.driver.switch_to.window(nowhandler)if __name__ == '__main__':unittest.main()
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

二、参数化

在unittest测试框架中,参数化使用的库为:parameterized 安装方式为:pip3 install parameterized

参数化:

我们把相同的测试步骤,应用于不同的测试场景,那么我们就可以使用参数化了

可以解决的问题是可以使用少量的测试代码,来覆盖更多的测试场景

例如:我们测一下sina邮箱的登录模块,代码如下:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):def setUp(self) -> None: #前提self.driver=webdriver.Chrome()self.driver.get('https://mail.sina.com.cn/')self.driver.maximize_window()self.driver.implicitly_wait(30)def tearDown(self) -> None: #清理self.driver.quit()def test_sina_null(self):'''sina邮箱验证:登录账户为空'''self.driver.find_element_by_class_name('loginBtn').click()divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')self.assertEqual(divText.text,'请输入邮箱名')def test_sina_email_format(self):'''sina邮箱验证:登录邮箱格式不正确'''self.driver.find_element_by_id('freename').send_keys('qwert')self.driver.find_element_by_class_name('loginBtn').click()divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')self.assertEqual(divText.text,'您输入的邮箱名格式不正确')def test_sina_username_error(self):'''sina邮箱验证:登录账户不匹配'''self.driver.find_element_by_id('freename').send_keys('asdf@sina.com')self.driver.find_element_by_id('freepassword').send_keys('asdfg')self.driver.find_element_by_class_name('loginBtn').click()t.sleep(3)divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')self.assertEqual(divText.text,'登录名或密码错误')if __name__ == '__main__':unittest.main()

由于登录模块主要是⽤户名和密码的input表单的验证以及错误信息的验证,我们可以把用户名、密码、错误信息的验证参数化,具体实现的代码如下:

 from selenium import  webdriver
import  unittest
import  time as t
from parameterized import  parameterized,param
class BaiduTest(unittest.TestCase):def setUp(self) -> None: #前提self.driver=webdriver.Chrome()self.driver.get('https://mail.sina.com.cn/')self.driver.maximize_window()self.driver.implicitly_wait(30)def tearDown(self) -> None: #清理self.driver.quit()@parameterized.expand([param('','','请输入邮箱名'),param('wertasd', 'asdf', '您输入的邮箱名格式不正确'),param('wertasd@sina.cn', 'asdf', '登录名或密码错误')])def test_sina_login(self,username,password,result):self.driver.find_element_by_id('freename').send_keys(username)t.sleep(3)self.driver.find_element_by_id('freepassword').send_keys(password)t.sleep(3)self.driver.find_element_by_class_name('loginBtn').click()t.sleep(3)divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')self.assertEqual(divText.text,result)

三、断言

assertEqual

assertEqual()是验证两个值相等,值的是数据类型与内容也是相等的,⻅案例代码:

from selenium import webdriver
import unittest
class BaiduTest(unittest.TestCase):def setUp(self) -> None:self.driver=webdriver.Chrome()self.driver.get('http://www.baidu.com')self.driver.maximize_window()self.driver.implicitly_wait(30)def tearDown(self) -> None:self.driver.quit()def test_baidu_title(self):'''百度测试:验证百度首页的title'''# assert self.driver.title=='百度一下,你就知道'self.assertEqual(self.driver.title,'百度一下,你就知道')

assertTrue

返回的是bool类型,也就是对被测试的对象进⾏验证,如果返回的是boolean类型并且是true,那么结果验证通过,那么⽅法assertFlase()验证的是被测试对象返回的内容是false,⻅案例代码:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):def setUp(self) -> None: #前提self.driver=webdriver.Chrome()self.driver.get('https://mail.sina.com.cn/')self.driver.maximize_window()self.driver.implicitly_wait(30)def tearDown(self) -> None: #清理self.driver.quit()def test_sina_isLogin(self):'''sina邮箱验证,判断自动登录是否勾选'''isLogin=self.driver.find_element_by_id('store1')self.assertTrue(isLogin.is_selected())

assertIn

assertIn()值的是⼀个值是否包含在另外⼀个值⾥⾯,在这⾥特别的强调⼀下,在assertIn()的⽅法⾥⾯,有两个参数,那么值的包含其实就是第⼆个实际参数包含第⼀个实际参数。与之相反的⽅法是assergNotIn(),⻅案例代码:

import unittest
from selenium import webdriver
class UiTest(unittest.TestCase):
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
def tearDown(self) -> None:
self.driver.quit()
def test_baidu_title_001(self):
self.assertIn('百度',self.driver.title)
def test_baidu_title_002(self):
self.assertIn('百度⼀下,你就知道',self.driver.title)
if __name__ == '__main__':
unittest.main()

四、测试报告

在unittest的框架中,⽣成测试报告需要使⽤到HTMLTestRunner

import unittest
import os
from 单元测试框架.HTMLTestRunner import HTMLTestRunner #从HTMLTestRunner模块调用HTMLTestRunner类def getTests():'''加载所有的测试模块'''suite=unittest.TestLoader().discover(#找到被执行模块的路径start_dir=os.path.dirname(__file__),#加载路径下所有以test_开头的测试模块的文件pattern='test_*.py' #正则表达式)return suitedef runSuite():unittest.TextTestRunner().run(getTests())def base_dir():return os.path.dirname(os.path.dirname(__file__))#获取当前目录的上级目录def run():fp=open(os.path.join(base_dir(),'report','report.html'),'wb')#拼接report.html的路径 wb 二进制的方式写入runner=HTMLTestRunner(stream=fp,  #流 执行一个写入一个title='UI自动化测试报告',description='' )runner.run(getTests())if __name__ == '__main__':run()

怎么解决每次生成的测试报告不覆盖之前的测试报告,同时被保留:

解决方法:引入时间库获取时间戳

代码如下:

import time
import unittest
import os
from HTMLTestRunner import HTMLTestRunnerdef getTests():'''加载所有的测试模块'''suite=unittest.TestLoader().discover(#找到被执行模块的路径start_dir=os.path.dirname(__file__),#加载路径下所有以test_开头的测试模块的文件pattern='test_*.py' #正则表达式)return suitedef getNowTime():return time.strftime('%y-%m-%d %H-%M-%S',time.localtime(time.time()))def base_dir():return os.path.dirname(os.path.dirname(__file__))def run():fp=open(os.path.join(base_dir(),'report',getNowTime()+'report.html'),'wb')runner=HTMLTestRunner(stream=fp,title='UI自动化测试报告',description='')runner.run(getTests())if __name__ == '__main__':run()

这样每次执行的都会生成一个测试报告:

END今天的分享就到此结束了,点赞关注不迷路~

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

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

相关文章

新登录接口独立版变现宝升级版知识付费小程序-多领域素材资源知识变现营销系统

源码简介: 资源入口 点击进入 源码亲测无bug,含前后端源码,非线传,修复最新登录接口 梦想贩卖机升级版,变现宝吸取了资源变现类产品的很多优点,摒弃了那些无关紧要的东西,使本产品在运营和变现…

MVC、MVP、MVVM区别

MVC、MVP、MVVM区别 MVC(Model-View-Controller) 。是一种设计模式,通常用于组织与应用程序的数据流。它通常包括三个组件:模型(Model)、视图(View)和控制器(Controller&…

TDengine 上榜 BenchCouncil 全球首个开源贡献榜

近日,Bench Council(国际测试委员会)公布了“世界首个开源贡献榜”,该榜单号称“只以贡献分高下”。值得一提的是,涛思数据、TDengine 上榜 BenchCouncil 发布的开源计算机系统机构榜、成果榜,TDengine 创始…

CDN策略好坏的重要性

CDN加速技术在今天的互联网世界中扮演着至关重要的角色,它可以显著提高网站和应用程序的性能,同时也有助于提供更好的安全性。然而,设定安全策略的好坏对CDN的影响是一个关键的议题,本文将深入探讨这个问题。 CDN(内容…

2、Sentinel基本应用限流规则(2)

2.2.1 是什么 Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 2.2.2 基本概念 • 资源 (需要被保护的东西…

宝马——使用人工智能制造和驾驶汽车

德国汽车制造商宝马(BMW)每年在全球制造和销售250万台汽车,其品牌包括宝马、MINI和劳斯莱斯。 宝马汽车以其卓越的性能和对新技术的应用而著名,它是道路上最精致的汽车之一,并且和其竞争对手戴姆勒(Daimler)一样,在将自动驾驶汽车…

Redis中的Zset类型

目录 Zset的相关命令 zadd zrange zcard zcount zrevrange zrangebyscore zpopmax bzpopmax zpopmin和bzpopmin zrank zrevrank zscore zrem zremrangebyrank zremrangebyscore 操作集合间的命令 zinterstore和zunionstore 内部编码 Zset的应用场景 Zset表…

独立键盘接口设计(Keil+Proteus)

前言 软件的操作参考这篇博客。 LED数码管的静态显示与动态显示(KeilProteus)-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/134101256?spm1001.2014.3001.5501实验:用4个独立按键控制8个LED指示灯。 按下k1键&#x…

Mysql进阶-视图篇

介绍 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。…

Si4010 一款带有MCU SoC RF发射机芯片 无线遥控器

Si4010是一款完全集成的SoC RF发射机,带有嵌入式CIP-51 8051 MCU,专为1GHz以下ISM频带设计。该芯片针对电池供电的应用进行了优化,工作电压为1.8至3.6 V,待机电流小于10 nA的超低电流消耗。高功率放大器可提供高达10 dBm的输出功率…

手术训练系统项目

★ 手术训练系统项目 项目描述:手术训练系统,它提供了多项功能,包括账户登录与创建、数据库与账户管理、课程管理、小组管理、成绩统计、证书发布、训练和系统设置。 职责描述: 1、训练功能开发(任务概述、任务指导、评分规则、评…

【数据结构】手撕单链表

目录 前言 1 链表 1.1 链表的概念及结构 1.2 链表的分类 1.2.1 单向或者双向 1.2.2 带头或者不带头 1.2.3 循环或者非循环 1.2.4 无头单向非循环链表 1.2.5 带头双向循环链表 2 链表的实现 2.1 结构 2.2 结点的创建 2.3 尾插 2.4 头插 2.5 尾删 2.6 头删 2.7 …

数据结构与算法之美学习笔记:17 | 跳表:为什么Redis一定要用跳表来实现有序集合?

目录 前言如何理解“跳表”?用跳表查询到底有多快?跳表是不是很浪费内存?高效的动态插入和删除跳表索引动态更新解答开篇内容小结 前言 本节课程思维导图: 二分查找底层依赖的是数组随机访问的特性,所以只能用数组来实…

2.求100-999之间的水仙花数

#include<stdio.h>void fun(void){int i,a,b,c;for(i100;i<1000;i) {ai%10;//个 b(i/10)%10;//十 ci/100;//百 if(ia*a*ab*b*bc*c*c)printf("%d ",i);}}int main(){fun();return 0;}

STM32 GPIO 描述

一、GPIO功能描述 每个GPIO端口有两个32位配置寄存器(GPIOx_CRL&#xff0c;GPIOx_CRH) &#xff0c;两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR) &#xff0c;一个32位置位/复位寄存器(GPIOx_BSRR)&#xff0c;一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR…

数据可视化:地图

1.基础地图的使用 如何添加颜色表示层级 代码实现 """基础地图的使用 """ from pyecharts.charts import Map from pyecharts.options import VisualMapOpts# 准备地图对象 map Map() # 准备数据 data [("北京市", 9),("上海市…

实验记录之——git push

平时做开发的时候经常push代码不成功&#xff0c;如下图 经好友传授经验&#xff0c;有如下方法 Win cmd使用Clash&#xff08;端口是7890&#xff09;代理操作&#xff0c;在cmd中输入&#xff1a; set http_proxy127.0.0.1:7890 set https_proxy127.0.0.1:7890Linux export …

有关LED显示屏对比度的知识

LED显示屏的对比度是指显示屏的亮度范围&#xff0c;即显示屏能够显示的最亮和最暗的部分之间的差异。对比度是一个重要的显示参数&#xff0c;它影响图像和视频的质量&#xff0c;以及用户对显示内容的感知。你知道LED显示屏的亮度和对比度是如何调节的吗&#xff1f; 一般来说…

【渗透测试】垂直越权(高危)、水平越权(中危)

目录 一、简介1.1 水平越权&#xff08;中危&#xff09;1.2 垂直越权&#xff08;高危&#xff09;1.3 方便记忆方法 二、修复方案2.1 水平越权修复2.2 垂直越权修复 一、简介 1.1 水平越权&#xff08;中危&#xff09; 漏洞危害&#xff1a; 水平越权 是相同级别&#xff0…

智能井盖传感器实时批发价格

城市之中高楼大厦林立&#xff0c;越来越多的人群涌入一线城市或二线城市。同时即便是县城之中接连不断的高楼大厦拔地而起&#xff0c;住宅小区的面积在不断拓宽。随着这一系列情况的出现&#xff0c;首先要完善的是每一个地区的城市道路设施建设。无论小区还是在城市路面之中…