湖南省建设工程造价管理总站/100个成功营销案例
目录
unittest的大致构成:
Test Fixture
Test Case-测试用例
Test Suite-测试套件
Test Runner
批量执行脚本
makeSuite()
TestLoader
discover()
用例的执行顺序
忽略用例执行
skip
skipIf
skipUnless
断言
HTML测试报告
错误截图
unittest是python中的单元测试框架
大致作用:
- 提供用例的组织与执行-组织大量的测试用例
- 提供丰富的比较方法-断言
- 提供丰富的日志-总执行时间,失败用例数,成功用例数
unittest的大致构成:
Test Fixture
对一个测试用例环境的搭建与销毁,就是一个Test Fixture(设备,固定之物).通过覆盖setUp()和tearDown()方法来实现
setUp()是测试环境的搭建,比如获取待测浏览器的驱动,或者如果测试中需要访问的数据库,可以在setUp()中建立数据库的连接来进行初始化.
tearDown()进行测试环境的销毁,关闭浏览器,关闭数据库等操作
Test Case-测试用例
一个TestCase的实例就是一个测试用例,测试用例就是一个完整的测试流程,包括测试环境的搭建(setUp),实现测试代码的过程,测试环境的销毁,还原(tearDown())
一个测试用例就是一个完整的测试单元
Test Suite-测试套件
将多个测试用例集合在一起
Test Runner
测试的执行,unittest框架中,通过TextTestRunner类提供的run方法执行testCase或testSuite
感受单元测试
from selenium import webdriver
import unittest
import time
from selenium.webdriver.common.by import Byclass Baidu2(unittest.TestCase):def setUp(self): # 测试环境的构建print("-----setUp-----呜啦啦")self.driver = webdriver.Edge()self.driver.implicitly_wait(30)self.url = "https://www.baidu.com/"self.driver.maximize_window()time.sleep(3)def tearDown(self): # 测试环境的销毁print("-----tearDown-----")self.driver.quit()def test_baidu(self): # 脚本1driver = self.driverurl = self.urldriver.get(url)driver.find_element(By.ID, "kw").send_keys("我的世界")driver.find_element(By.ID, "su").submit()time.sleep(2)print(driver.title)# self.assertNotEqual(driver.title, "百度一下_百度搜索", msg="不相等")# self.assertTrue("beautiful"=="beauty", msg="Not Equal!")time.sleep(2)def test_findB(self): # 脚本2driver = self.driverurl = self.urldriver.get(url)driver.find_element(By.ID, "kw").send_keys("B站")driver.find_element(By.ID, "su").submit()driver.find_element(By.LINK_TEXT, "哔哩哔哩(b站) - 哔哩哔哩 (゜-゜)つロ 干杯~-bi...").click()time.sleep(2)print(driver.title)time.sleep(2)if __name__ == "__main__":# unittest提供的全局main()方法,能够使一个单元测试模块轻松的变成可直接运行的测试脚本# 在main方法中搜索包含在此模块下的,以test命名的测试方法,并执行他们unittest.main()
在Baidu2这个类中,
- setUp + test_baidu + tearDown -> 第1个Test Case
- setUp + test_findB + tearDown -> 第2个Test Case
尝试将代码跑一下,可以发现.在每次执行被测试代码时,setUp与tearDown都会对应的执行一遍.
批量执行脚本
我们把一个web的每个功能模块都分成一个单元测试,那该怎么将每个模块的单元测试一起执行呢.
就要用到我们上面所提到的Test Suite(测试套件),其是一个集合,集合里装载着Test Case(测试用例)
使用测试套件的大致流程为:
- 创建一个测试套件 suite = unittest,TestSuite() #创建一个实例
- 把多个测试用例放入测试套件中 suite.addTest() #添加测试方法
- 执行测试套件 TextTestRunner的run方法启动suite
其中步骤2的addTest一次只能添加一个测试方法
下面介绍批量执行脚本的三种方式
makeSuite()
由unittest框架中提供的makeSuite()方法,能够把测试用例类内的所有测试用例组成一个TestSuite(测试套件),在使用此方法的时候只要把测试类名传入即可.
def createSuite1(): # makeSuitesuite1 = unittest.TestSuite() # 创建一个测试套件# 将MyUnitTest01中的Baidu1类中所有的test方法集合成Suite# 再将集合成的Suite通过addTest方法添加到我们所创建的Suite实例suite1中suite1.addTest(unittest.makeSuite(case.MyUnitTest01.Baidu1)) suite1.addTest(unittest.makeSuite(case.MyUnitTest02.Baidu2))return suite1if __name__ == "__main__":suite = createSuite0()# verbosity表示测试结果的信息复杂度,有0,1,2三个级别,复杂度随级别递增runner = unittest.TextTestRunner(verbosity=2) # 创建TextTestRunner实例runner.run(suite)
TestLoader
使用TestLoader,测试加载器将测试用例批量的加载到测试套件中
需要用到TestLoader的实例方法:loadTestsFromCase
def createSuite2():# 使用TestLoader加载器的实例方法,加载Baidu1类中的测试方法以suite类型返回a = unittest.TestLoader().loadTestsFromTestCase(case.MyUnitTest01.Baidu1)b = unittest.TestLoader().loadTestsFromTestCase(case.MyUnitTest02.Baidu2)# 将加载好的两个suite整合一下thesuite = unittest.TestSuite([a, b])return thesuite
discover()
上面的两种方式都要提前把类给导入
使用discover就不用添加类了,可以直接根据路径来匹配相应的文件
def createSuite3():# 根据所给出的路径,找到匹配正则表达式的文件中的test方法,并将找到的所有test方法以suite的形式返回# top_leve_dir一般设置None,默认值即可discover = unittest.defaultTestLoader.discover('./case', pattern='MyUnit*.py', top_level_dir=None)print(discover)return discover
用例的执行顺序
在unittest框架中默认加载测试用例的顺序是根据ASCII码的顺序
在一个模块中,命为TestA的方法会比TestB的方法优先执行.
而在suite中,会根据addTest()添加的顺序来执行
suite1中含有:
- testB
- testA
suite2中含有:
- test9
- test2
------------------------------
suite.addTest(suite2)
suite.addTest(suite1)
------------------------------
则最终的执行顺序为:
test2->test9->testA->testB
忽略用例执行
在unittest中想要把test方法进行跳过,可以使用unittest提供的skip标签
这里介绍三个标签:
- skip([原因])-无条件跳过标签
- skipIf([条件,原因])-有条件跳过标签
- skipUnless([条件,原因])-有条件跳过标签
skip
@unittest.skip("暂时跳过此方法")
def test_hao(self):driver = self.driverurl = self.urldriver.get(url)driver.find_element(By.LINK_TEXT, "hao123").click()time.sleep(2)
skipIf
比skip多了一个参数,布尔值.
如果为true,则跳过
@unittest.skipIf(2 < 1, "满足条件")
def test_hao(self):driver = self.driverurl = self.urldriver.get(url)driver.find_element(By.LINK_TEXT, "hao123").click()time.sleep(2)
skipUnless
与skipIf差不多,但与其相反
如果为false,则跳过
这里就不举例介绍啦~
断言
unittest框架的目的是对代码进行测试,查看结果是否符合我们的预期.
断言就起到了前面后半句的作用,查看结果是否符合我们的期望.
unittest中:
- 如果某一个case的断言不符合预期测试就会立即停止当前正在执行的case并生成错误信息(并不会影响其他case执行),
- 如果断言通过则继续执行下一个case
在unittest的单元测试库中提供了许多断言的方法,下面是一些常用的方法.
序 号 | 断言方法 | 断言描述 |
1 | assertEqual(arg1, arg2, msg=None) | 验证arg1=arg2,不等则fail |
2 | assertNotEqual(arg1, arg2, msg=None) | 验证arg1 != arg2, 相等则fail |
3 | assertTrue(expr, msg=None) | 验证expr是true,如果为false,则fail |
4 | assertFalse(expr,msg=None) | 验证expr是false,如果为true,则fail |
5 | assertIs(arg1, arg2, msg=None) | 验证arg1、arg2是同一个对象,不是则fail |
6 | assertIsNot(arg1, arg2, msg=None) | 验证arg1、arg2不是同一个对象,是则fail |
7 | assertIsNone(expr, msg=None) | 验证expr是None,不是则fail |
8 | assertIsNotNone(expr, msg=None) | 验证expr不是None,是则fail |
9 | assertIn(arg1, arg2, msg=None) | 验证arg1是arg2的子串,不是则fail |
10 | assertNotIn(arg1, arg2, msg=None) | 断言描述验证arg1不是arg2的子串,是则fail |
11 | assertIsInstance(obj, cls, msg=None) | 验证obj是cls的实例,不是则fail |
12 | assertNotIsInstance(obj, cls,msg=None) | 验证obj不是cls的实例,是则fail |
msg是自己定义给断言如果发生错误显示的信息
HTML测试报告
下载HTMLTestRunner.py,并将其扔到python的lib当中
import unittest
import HTMLTestRunner
import time
import os,sys
if __name__ == "__main__":curpath = sys.path[0] # 获取当前的根目录print(curpath)# 取当前时间now = time.strftime("%Y-%m-%d-%H %M %S", time.localtime(time.time()))# 查看是否有文件夹/resultreport,如果没有则创建if not os.path.exists(curpath + '/resultreport'):os.makedirs(curpath + '/resultreport')# 创建报告文件的名称: 根目录+resultreport(报告文件夹)+时间+html格式文件filename = curpath + '/resultreport/' + now + 'resultreport.html'# 写入创建的html文件中# 打开文件,模式为二进制写wb,文件变量名为fpwith open(filename, 'wb') as fp:runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=u'测试报告',description=u'用例执行情况',verbosity=2)suite = createSuite1()# verbosity表示测试结果的信息复杂度,有0,1,2三个级别,复杂度随级别递增runner.run(suite)
错误截图
在断言没通过的时候,我们可以设置自动截图来查看当时的web情况如何,这样就能方便我们对测试用例的观察
def savescreenshot(driver, file_name):if not os.path.exists('./image'):os.makedirs('./image')cur = time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))# 截图保存driver.get_screenshot_as_file('./image/'+cur+'-'+file_name)time.sleep(1)
def test_baidu(self):driver = self.driverurl = self.urldriver.get(url)driver.find_element(By.ID, "kw").send_keys("蜡笔小新")driver.find_element(By.ID, "su").submit()time.sleep(2)try:self.assertEquals("haha", "wowo")except:savescreenshot(driver, 'wow.png')time.sleep(2)
相关文章:

[Python]unittest-单元测试
目录 unittest的大致构成: Test Fixture Test Case-测试用例 Test Suite-测试套件 Test Runner 批量执行脚本 makeSuite() TestLoader discover() 用例的执行顺序 忽略用例执行 skip skipIf skipUnless 断言 HTML测试报告 错误截图 unittest是python中的单元测…...

Jetpack:021-Jetpack中的滑动列表
文章目录 1. 概念介绍2. 使用方法2.1 函数参数2.2 列表成员 3. 示例代码4. 内容扩展5. 内容总结 我们在上一章回中介绍了Jetpack中底部导航栏相关的内容,本章回中主要介绍 滑动列表。闲话休提,让我们一起Talk Android Jetpack吧! 1. 概念介绍…...

基于单片机的空气质量检测系统
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、主要内容二、系统方案设计2.1 系统方案设计2.2 主控制器模块选择 三、 系统软件设计4.1 程序结构分析4.2系统程序…...

论文阅读——InstructGPT
论文:Training_language_models_to_follow_instructions_with_human_feedback.pdf (openai.com) github:GitHub - openai/following-instructions-human-feedback 将语言模型做得更大并不能从本质上使它们更好地遵循用户的意图。例如,大型语…...

【表面缺陷检测】铝型材表面缺陷检测数据集介绍(含xml标签文件)
一、铝型材介绍 铝型材是一种由铝合金材料制成的,具有固定截面形状和尺寸的条形建材。由于其优良的物理性能和广泛的应用领域,铝型材在现代工业和生活中发挥着重要的作用。 1、铝型材的分类 根据截面形状的不同,铝型材可分为角铝、槽铝、工…...

我的学习:从本科到研究生的认识与实践经验总结
学习实践经历 18年 上大学以后,因为对计算机的喜爱和对未知编程技术的好奇和探索,选择了从零开始学习程序设计,经过实践,选择了转专业到计算机科学与技术,开始了我的计算机学习之路。 19年 因为想要拓宽自己的专业能力…...

云游长江大桥,3DCAT实时云渲染助力打造沉浸化数字文旅平台
南京长江大桥是中国第一座自主设计建造的双层公路铁路桥,也是世界上最早的双层公路铁路桥之一。它不仅是一座桥梁,更是一座历史文化的见证者和传承者。它见证了中国人民的智慧和奋斗,承载了中国社会的变迁和发展。 如何让这座不可移动的文物…...

【音视频|PCM】PCM格式详解
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

行为型模式-行为型模式
在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。 意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类…...

openpnp - Warning - Unknown firmware
文章目录 openpnp - Warning - Unknown firmware概述笔记https://github.com/openpnp/openpnp/wiki/Motion-Controller-Firmwares备注END openpnp - Warning - Unknown firmware 概述 接上飞达控制板后, 显示未知固件的警告 开始没看源码之前, 总以为是回答的版本号不合适, …...

Android 中如何使用 App Links
1. 简介 什么是 App Links呢?App Links 是 Android 6.0 (API 级别23) 引入的新功能,它是基于 DeepLinking,允许应用自动处理网站的 URL,而无需提示用户启动相应的应用。 例如:如果你在手机浏览器中输入了某个网站&am…...

7 款好用的 PDF 密码删除工具
这是最佳 PDF 密码删除工具列表。该列表包括免费和付费软件。将要在线完成的所有事情都需要密码才能感到安全。数据传输也是如此。大多数数据是通过文件传输的,PDF有自己的标志。PDF是一种灵活的文件格式,因此也可以专业使用。 有多种PDF 编辑器软件&am…...

你一般什么时候会用到GPT?
GPT(Generative Pre-trained Transformer)是一种自然语言处理技术,它在各种领域和场景中都有广泛的应用。下面将详细介绍一些常见的情况,人们在这些情况下通常会使用GPT: 自然语言生成: GPT可以用于生成文本…...

YUV编码格式解析
YUV 颜色编码 YUV 颜色编码采用的是 明亮度 和 色度 来指定像素的颜色。 其中,Y 表示明亮度(Luminance、Luma),而 U 和 V 表示色度(Chrominance、Chroma)。 而色度又定义了颜色的两个方面:色…...

mysql-面试50题-5
一、查询数据 ymysql-面试50题-2-CSDN博客 二、问题 41.按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一 mysql> select student.SId as 学生编号,student.Sname as 学生姓名, -> TIMESTAMPDIFF(YEAR,student.Sage,CURDATE(…...

微服务初始和Nacos安装
一)初始微服务: 微服务是将一个大型的,单一的应用程序拆分成多个小型服务,每一个服务负责于特定的业务功能,并且可以通过网络来和其他服务进行通讯,是一个思想,将一个大的项目拆分成多个小的项目,多个小的项…...

YouTube博主数据信息资源
YouTube博主数据信息资源 🔥我是一位拥有10年编程经验的程序猿,为你带来一个全新的优质资源 🔍您是否在寻找最新、最活跃的YouTube博主数据,以助力你的项目、营销或研究? 我们的数据,您的优势:…...

算法通过村第十七关-贪心|黄金笔记|跳跃游戏
文章目录 前言跳跃游戏最短跳跃游戏总结 前言 提示:曾走过山,走过水,其实只是借助他们走过我的生命;我看着天,看着地,其实只是借助它们确定我的位置;我爱这她,爱着你,其实…...

【精选】VMware部署ESXI6.5 vCenter Server详解
VMware部署ESXI6.5 vCenter Server 一、ESXi主机介绍1、虚拟机的好处2、为什么要使用虚拟机 二、虚拟化服务器概述1、VSphere物理架构2、体系架构3、VMware vSphere 组件 三、ESXi安装环境1、安装步骤2、使用VMware新建ESXi主机3、初始环境安装 四、创建虚拟机五、安装部署VMwa…...

如何借助数据集更好的评估NLP模型的性能?
随着信息时代的迅猛发展,每天有无数文本、声音、图片和视频不断涌入互联网。如何从海量数据中提炼有意义信息成为学术界和工业界迫切需要解决的问题。在此背景下,自然语言处理(NLP)应运而生,成为人工智能领域最为活跃的…...

2023年腾讯云服务器地域节点选择指南(亲自整理)
腾讯云轻量应用服务器地域是指轻量服务器数据中心所在的地理位置,如上海、广州和北京等地域,如何选择地域?腾讯云百科txybk.com建议地域选择遵循就近原则,用户距离轻量服务器地域越近,网络延迟越低,速度就越…...

华媒舍:日韩媒体发稿推广中8个关键因素帮助你实现突破
在当今经济全球化的时代背景下,日韩地域媒体影响力日益提高。对于需要在这一地区开展发稿推广的人来讲,掌握适度的思路和流程是十分重要的。下面我们就为大家介绍8个关键因素,以帮助你在日韩地域媒体发稿推广中实现突破。 1.科学研究行业在逐…...

Docker数据卷
目录 1.bind mount 2.docker managed volume 1.bind mount docker run -it --rm -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/passwd:/mnt/passwd:ro busybox 2.docker managed volume docker run -d --name web1 webserver:v3 docker inspect web1 cd/var/lib/doc…...

LightGBM 的完整解释 - 最快的梯度提升模型
文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的…...

Think-Queue3一直提示[Exception]redis扩展未安装
场景 tp6tq3实现的任务队列,使用redis作为数据驱动,目前是tp6可以正常使用redis了,但tq3不行,一直提示[Exception]redis扩展未安装。 解决思路 1.分析tq3源码 定位到是这一行出了问题 if (!extension_loaded(redis)) {throw n…...

Spring cloud教程Gateway服务网关
Spring cloud教程|Gateway服务网关 写在前面的话: 本笔记在参考网上视频以及博客的基础上,只做个人学习笔记,如有侵权,请联系删除,谢谢! Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,…...

【C++代码】爬楼梯,不同路径,整数拆分,不同搜索树,动态规划--代码随想录
动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推…...

设计模式(单例模式、工厂模式及适配器模式、装饰器模式)
目录 0 、设计模式简介 一、单例模式 二、工厂模式 三、适配器模式 四、装饰器模式 0 、设计模式简介 设计模式可以分为以下三种: 创建型模式:用来描述 “如何创建对象”,它的主要特点是 “将对象的创建和使用分离”。包括单例、原型、工厂方法、…...

为wget命令设置代理
使用-e参数 wget本身没有专门设置代理的命令行参数,但是有一个"-e"参数,可以在命令行上指定一个原本出现在".wgetrc"中的设置。于是可以变相在命令行上指定代理: -e, --executeCOMMAND 执行.wgetrc格式的命令 例如&…...

【C++深入浅出】模版初识
目录 一. 前言 二. 泛型编程 三. 函数模版 3.1 函数模版的概念 3.2 函数模版的格式 3.3 函数模版的原理 3.4 函数模板的实例化 3.5 模板参数的匹配原则 四. 类模版 4.1 类模版的定义 4.2 类模版的实例化 一. 前言 本期我们要介绍的是C的又一大重要功能----模版。通…...