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) 包:用来从逻 ...
随机推荐
- java试用静态图片制作gif
参考博客:https://www.cnblogs.com/dreammyle/p/4843365.html 代码中需要的依赖: <!-- gif --> <dependency> ...
- 使用tkinter打造一个小说下载器,想看什么小说,就下什么
前言 今天教大家用户Python GUI编程--tkinter 打造一个小说下载器,想看什么小说,就下载什么小说 先看下效果图 Tkinter 是使用 python 进行窗口视窗设计的模块.Tkint ...
- rman删除归档日志无法释放
背景 当Oracle 归档日志满了后,将无法正常登入oracle,需要删除一部分归档日志才能正常登入ORACLE.最近遇到一个问题,一套Oracle 11g数据库使用RMAN删除了归档日志,但是仍然无 ...
- 2020-2021-1 20209307《Linux内核原理与分析》第七周作业
这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第七周作业> 这个作业的目标 & ...
- Cookie注入新方法
正常输 and 1=1 会有waf 进行拦截 判断一个网站是否支持cookie注入_> 现在是get ,你可以把参数放在post里面试试看看是否返回正常 用hackbar插件也 ...
- 作为Java新手,如何才能快速的看透一个Java项目?
前言 技术学习是一个总结.纠错.触类旁通的过程,而不是单纯重复练习的过程,如果你问一个做过5年以上Java的老码农,他们很多人都会有很强的"搬砖感",这种"搬砖感&quo ...
- 制作3D小汽车游戏(上)
之前一段时间家里和公司的事太多,一直没有时间写博客,最近腾出一段时间,看了一遍官方的examples,收货颇多,想整理一点东西出来,又苦于没有好的东西,three写点东西真是太难了.好吧,今天郭先生就 ...
- 分布式文件系统之 FastDFS
FastDFS 百度百科 FastDFS 是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合 ...
- 【代码周边】Idea设置类注解和方法注解(带图)
Idea版本: 类注解 打开setting→Editor→Code Style→File and Code Templates /** * Created with IntelliJ IDEA. * ...
- [leetcode]48RotateImage二维数组翻转
import java.util.Arrays; /** * You are given an n x n 2D matrix representing an image. Rotate the im ...