python模块详解 | unittest(单元测试框架)(持续更新中)
目录:
why unittest?
- unittest的四个重要概念
- 加载测试用例的三个方法
- 自动加载测试用例
- 忽略测试和预期失败
- 生成html测试报告
why unittest?
简介:
Unittest是python自带的单元测试框架,设计灵感来自Java中的Juint,具有和Junit类似的结构
优点:
- 不仅可以用于单元测试,还适用于自动化测试用例的开发与执行
- 可阻止执行测试用例
- 断言预期结果
- 批量执行测试用例
- 最终可生成测试结果
unittest四个重要的概念:
1.1、测试用例(TestCase)
- 测试用例是单元测试中最基本的组成单元
- Unittest使用TestCase类(可自行命名)来表示测试用例,所有执行测试的类继承自该类
- 一个测试用例包括:测试固件、具体测试业务的函数或者方法
- 测试用例中,测试固件可以省略,但是至少有一个以test开头的测试函数testXXX
- Unittest会自动化识别test开头的函数为测试代码,所有的测试函数都要以test开头(如testXXX,注意test是小写),如果函数不以test开头,则Unittest不会执行函数
- 例:
import unittest
# 自定义一个测试实例类,传入unittest的测试实例类TestCase
class TestBaidu(unittest.TestCase):
driver=webdriver.Chrome()
driver.get(bd_url)
def test_1(self):
print(1)
# 断言等于
self.assertEqual(self.driver.title,u'百度一下,你就知道')
def test_2(self):
print(2)
# 断言为真
self.assertTrue(self.driver.find_element_by_id('kw').is_enabled())
if __name__ == '__main__':
unittest.main()
1.2、测试固件(setUp、tearDown)
- setUp()
- 在每个测试用例运行前运行,该方法用于进行测试前的初始化工作
- 一条用例执行一次,若N次用例就执行N次,根据用例的数量来定
- tearDown()
- 在每个测试用例运行后运行,该方法用于执行测试后的清除工作(不管是否执行成功)
- setUp()
- 例:
import unittest
# 自定义一个测试实例类,传入unittest的测试实例类TestCase
class TestBaidu(unittest.TestCase):
def setUp(self):
print('一个测试用例前的初始化工作...')
self.driver = webdriver.Chrome()
self.driver.get(bd_url)
def tearDown(self):
print('一个测试用例前的清除工作...')
self.driver.quit()
def test_1(self):
print(1)
# 断言等于
self.assertEqual(self.driver.title,u'百度一下,你就知道')
def test_2(self):
print(2)
# 断言为真
self.assertTrue(self.driver.find_element_by_id('kw').is_enabled())ps:1、如果setUp()执行成功(没有异常),那么无论测试方法是否通过,tearDown()都会被执行;
2、setUp()和tearDown()方法存在弊端,例如每次执行用例是都会重新打开,导致时间浪费,因此可以使用下面两种方法;
- setUpClass()
- 所有用例执行前只运行一次,在所有用例执行之前准备一次环境
- tearDownClass()
- 所有用例执行完后只运行一次,在所有用例执行结束后再清理环境
- 例:
import unittest
# 自定义一个测试实例类,传入unittest的测试实例类TestCase
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print('所有测试用例前的准备工作...')
cls.driver=webdriver.Chrome()
cls.driver.get(bd_url)
@classmethod
def tearDownClass(cls) -> None:
print('所有测试用例执行后的清理工作...')
cls.driver.quit()
def setUp(self):
print('一个测试用例前的初始化工作...')
self.driver = webdriver.Chrome()
self.driver.get(bd_url)
def tearDown(self):
print('一个测试用例前的清除工作...')
self.driver.quit()
def test_1(self):
print(1)
# 断言等于
self.assertEqual(self.driver.title,u'百度一下,你就知道')
def test_2(self):
print(2)
# 断言为真
self.assertTrue(self.driver.find_element_by_id('kw').is_enabled())
if __name__ == '__main__':
unittest.main()
- 例:
1.3、测试套件(TestSuite)
- 完整的单元测试很少只执行一个测试用例,开发人员通常都需要编写多个测试用例才能对某一软件功能进行完整的测试
- 测试套件是多个测试用例或者测试用例集合聚合组织起来的集合,是针对被测程序对应的功能和模块创建的一组测试,测试套件内的测试用例将一起执行,即批量执行一个测试套件内所有的测试用例
- 在unittest中,测试套件主要通过unittest.TestSuite()类直接构建,或者通过TestSuite实例的addTests、addTest方法构建
- 例:
if __name__ == '__main__':
# 测试套件写法1
suite1=unittest.TestSuite(map(TestBaidu,['test_1','test_2']))
# 测试套件写法2
suite2=unittest.TestSuite()
suite2.addTests(map(TestBaidu,['test_1','test_2']))
# 测试套件写法3
suite3 = unittest.TestSuite()
suite3.addTest(TestBaidu('test_1'))
suite3.addTest(TestBaidu('test_2'))
1.4、测试执行器(TextTestRunner)
- 测试执行器是一个组织安排测试脚本执行活动的组件,即用来加载测试用例并执行用例,且提供测试输出的一个组件
- 测试执行器负责测试执行调试并且通过一些图形界面,文本界面或者返回一些特殊的值来展示测试脚本的测试结果给用户
- 测试的执行也是单元测试中非常重要的一个概念,一般单元测试框架中都会提供丰富的执行策略和执行结果
- 测试执行器可以加载测试用例或者测试套件来执行测试任务,即利用猜测是执行器加载的测试用例,可以是单个测试用例,也可以是套件
- 例:
#测试执行器
runner=unittest.TextTestRunner()
runner.run(suite)
加载测试用例的三个方法
2.1 unittest.main()
- 两个参数(exit、verbosity):
exit | exit=False表示中间有用例失败也继续执行 |
verbosity |
若verbosity=0,则输出简单报告,获得总的测试用例数和总的结果。比如,总共100个,失败20 成功80; 若verbosity=1,则输出一般报告,每个成功的用例前面有个“.”,每个失败的用例前面有个“F”,默认值为1; 若verbosity=2,则输出详细报告,测试结果会显示每个测试用力的所有相关的信息; 添加参数--quite,等效于verbosity=0; 添加参数--version,等效于verbosity=2; 不增加,等效于verbosity=1; |
- 例:
if __name__ == '__main__':
unittest.main()
- 例:
2.2 测试套件(TestSuite)
- 步骤:
- 创建测试套件
- 构建测试套件
- 使用测试执行器运行测试套件
- 参考:测试套件
2.3 unittest.TestLoader()
- 步骤:
- 加载测试用例:unittest.Loader()
- 添加测试用例到测试套件
- 使用测试执行器运行测试套件
- 实例化runner类:runner=unittest.TextTestRunner()
- 运行测试:runner.run(suite)
- unittest.TestLoader()加载测试用例的方法:
TestLoader().loadTestsFromTestCase(testCaseClass) | testCaseClass必须是TestCase的子类(或者孙类) |
TestLoader().loadTestsFromModule(module,pattern=None) | module是测试用例所在的模块 |
TestLoader().loadTestsFromName(name,module=None) | name是测试用例的方法名,使用格式是“module.class.method” |
TestLoader().loadTestsFromNames(names,module=None) |
- 方法图示:
- 例:
#加载测试用例
test_case=unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
#加载测试套件
suite=unittest.TestSuite()
suite.addTest(test_case)
#执行测试
runner=unittest.TextTestRunner()
runner.run(suite)
自动加载测试用例
简介:
unittest的TestLoader类提供了一个discover方法,以递归的方式,实现从指定顶层目录、模块找到指定目录里的测试用例文件,并将查找到的测试用例文件组装到测试套件中,然后运行。
- discover(start_dir,pattern,top_level_dirt):
start_dir | 被测试的模块或测试用例所在的目录 |
pattern | 用例文件名的匹配原则(默认匹配test*.py) |
top_level_dir | 测试模块的顶层目录,如果没有顶层目录,默认为None |
- 步骤:
- 获取目录下满足条件的所有包含测试用例的py文件,构造测试集
- 实例化测试执行器,运行测试用例
- 例:
#discover()方法加载所有测试用例进行测试
discover = unittest.TestLoader.discover(start_dir='./',
pattern='*.py',
top_level_dir=None)
#实例化测试执行器
runner = unittest.TextTestRunner()
#运行测试用例
runner.run(discover)
忽略测试和预期失败
@unittest.skip(reason) | 无条件跳过被装饰的测试方法,并说明跳过测试的原因;miaosureson:理由,描述为什么跳过测试用例 |
@unittest.skipIf(condition,reason) | 条件为真时,跳过被装饰的测试用例,并说明跳过测试的原因 |
@unittest.skipUnless(condition,reason) | 除非条件为真,否则跳过被装饰的测试用例;即条件为假时,跳过装饰的测试用例,并说明跳过测试的原因 |
@unittest.expectedFailure | 将测试用例标记为“预期失败” |
@unittest.SkipTest(reason) | 当需要跳过一个测试方法时,可以在测试方法或setup()中调用该方法 |
例:
class BaiduTest2(unittest.TestCase):
def setUp(self) -> None:
print('\n测试开始...')
self.driver=webdriver.Firefox()
self.driver.get(bd_url)
def tearDown(self) -> None:
self.driver.quit()
print('测试结束...')
@unittest.skip('跳过此测试,没有为什么')
def test1(self):
self.driver.find_element_by_id('kw').send_keys(keywords[0])
self.driver.find_element_by_id('su').click()
time.sleep(1)
print(self.driver.title)
self.assertEqual(self.driver.title,'Python_百度搜索')
@unittest.skipIf(condition=1<2,reason='又跳过了,因为2大于1')
def test2(self):
self.driver.find_element_by_id('kw').send_keys(keywords[1])
self.driver.find_element_by_id('su').click()
time.sleep(1)
print(self.driver.title)
self.assertEqual(self.driver.title,'Selenium_百度搜索')
@unittest.skipUnless(condition=1<2,reason='2大于1,执行此测试')
def test3(self):
self.driver.find_element_by_id('kw').send_keys(keywords[2])
self.driver.find_element_by_id('su').click()
time.sleep(1)
print(self.driver.title)
self.assertEqual(self.driver.title,'TestSuite_百度搜索')
html测试报告
5.1、配置HTMLTestRunner
- 工具:HTMLTestRunner
- 下载:http://tungwaiyip.info/software/HTMLTestRunner.html
- 安装:
Windows:将HTMLTestRunner.py文件移动到python安装目录下的lib文件夹内
Linux:将文件移动到安装目录下的第三方包文件夹(dist-packages)目录下
- 修改HTMLTestRunner.py文件,原因:由于下载的文件是基于python2语法,若使用的是python3,则需要修改
行数 | 修改前 | 修改后 |
94 |
import StringIO |
import io |
539 |
self.outputBuffer = StringIO.StringIO() |
self.outputBuffer = io.StringIO() |
631 |
print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime) |
print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)) |
642 |
if not rmap.has_key(cls): |
if not cls in rmap: |
766 |
uo = o.decode('latin-1') |
uo = e |
768 |
uo = o |
uo = o.decode('utf-8') |
772 |
ue = e.decode('latin-1') |
ue = e |
774 |
ue = e |
ue = e.decode('utf-8') |
5.2、生成测试报告
配置htmltestrunner成功后,在测试代码中导入HTMLTestRunner模块,并在测试文件中加入下述代码即可
python模块详解 | unittest(单元测试框架)(持续更新中)的更多相关文章
- python模块详解 | selenium(持续更新中)
目录: 关于selenium Selenium 安装Selenium 安装浏览器驱动 配置环境变量 selenium方法详解 定位元素 元素操作 浏览器操作 鼠标事件 浏览器事件 设置元素等待 多表单 ...
- Python 模块详解及import本质
同在当前目录下的模块和包导入 模块定义 本质就是.py结尾的python文件. 用来从逻辑上组织python代码(变量,函数,类,逻辑) 文件名: test.py; 对应的模块名 : test 模块 ...
- python模块详解 random os
random模块 常用方法 random.random() 随机产生一个小于1的浮点数 import random print(random.random()) #0.4153761818276826 ...
- python爬虫scrapy项目详解(关注、持续更新)
python爬虫scrapy项目(一) 爬取目标:腾讯招聘网站(起始url:https://hr.tencent.com/position.php?keywords=&tid=0&st ...
- python模块详解
什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.p ...
- python模块详解 sys shutil
sys模块 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sy ...
- python模块详解 | shutil
简介: shutil是python的一个内置模块,提供了许多关于文件和文件集合的高级操作,特别提供文件夹与文件操作.归档操作了支持文件复制和删除的功能. 文件夹与文件操作: copyfileobj(f ...
- 小白的Python之路 day5 python模块详解及import本质
一.定义 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能) 本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻辑上组织模块 ...
- Python模块详解以及import本质,获得文件当前路径os.path.abspath,获得文件的父目录os.path.dirname,放到系统变量的第一位sys.path.insert(0,x)
模块介绍 1.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻 ...
随机推荐
- 看我如何用微信上线CobaltStrike
前言 DLL劫持漏洞是老生常谈的一个漏洞,已经被前辈们各种奇技淫巧玩烂.但DLL劫持技术在后渗透和域渗透中的权限提升和权限维持都起到了至关重要的作用.本文简单剖析DLL劫持技术并通过实例应用来查看如何 ...
- 精尽Spring MVC源码分析 - 调式环境搭建
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- C++异常之五 异常和继承
异常和继承 异常也是类,我们可以创建自己的异常类,在异常中可以使用(虚函数,派生,引用传递和数据成员等), 下面用一个自制的数组容器Vector,在对Vector初始化时来对Vector的元素个数进行 ...
- JVM虚拟机(二):字节码执行引擎
运行时栈帧结构 栈帧是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈的栈元素.栈帧存储了方法的局部变量表.操作数栈.动态链接.和方法返回地址等信息. ...
- 面试 11-01.ES6:模块化的使用和编译环境
11-01.ES6:模块化的使用和编译环境 #前言 #ES6的主要内容 模块化的使用和编译环境 Class与JS构造函数的区别 Promise的用法 ES6其他常用功能 本文来讲"模块化的使 ...
- 2020软件测试工程师面试题汇总(内含答案)-看完BATJ面试官对你竖起大拇指!
测试技术面试题 1.什么是兼容性测试?兼容性测试侧重哪些方面? 参考答案: 兼容测试主要是检查软件在不同的硬件平台.软件平台上是否可以正常的运行,即是通常说的软件的可移植性. 兼容的类型,如果细分的话 ...
- 工具-效率工具-listary快速打开文件,win+R使用(99.1.1)
@ 目录 1.使用WIN+R打开软件 2.使用listary软件 1.使用WIN+R打开软件 添加环境变量 找到需要打开应用的目录 如我的桌面(C:\Users\Public\Desktop) 添加p ...
- matplotlib的学11-image图片
import matplotlib.pyplot as plt import numpy as np ''' 这一节我们讲解怎样在matplotlib中打印出图像. 这里我们打印出的是纯粹的数字,而非 ...
- C#中搜索xsd文件中的某个数据源
步骤 1.打开***.xsd文件. 2.数据源之间的空白处,右键->属性. 3.在VS右侧会跳出一个属性窗口. 4.有个名称为DataSet的下拉框,所有的数据源名称都在其中,单击即可定位到所选 ...
- 读取 excel文件组装字典数据
package com.murong.ecp.app.mbu.action.bmbuurm8; import java.io.FileOutputStream;import java.io.Outpu ...