Python单元测试框架——unittest
测试的常用规则
- 一个测试单元必须关注一个很小的功能函数,证明它是正确的;
- 每个测试单元必须是完全独立的,必须能单独运行。这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作。通常通过setUp()和setDown()方法处理;
- 编写执行快速的测试代码。在某些情况下,测试需要加载复杂的数据结构,而且每次执行的时候都要重新加载,这个时候测试执行会很慢。因此,在这种情况下,可以将这种测试放置一个后台的任务中。
- 采用测试工具并且学着怎么使用它。
- 在编写代码前执行完整的测试,而且在编写代码后再重新执行一次。这样能保证你后来编写的代码不会破坏任何事情;
- 在提交代码前执行完整的测试;
- 如果在开发期间被打断了工作,写一个打断的单元测试,关于你下一步将要开发的。当你回来工作时,你能知道上一步开发到的指针;
- 单元测试函数使用长的而且具有描述性的名字。在正式执行代码中,可能使用square()或sqr()取名,但是在测试函数中,你必须取像test_square_of_number_2()、test_square_negativer_number()这些名字,这些名字描述更加清楚;
- 测试代码必须具有可读性;
- 单元测试对新进的开发人员来说是工作指南。
二、常见的测试框架
2.1 Unittest
unittest是Python内置的标准类库。它的API跟Java的JUnit、.net的NUnit,C++的CppUnit很相似。
通过继承unittest.TestCase来创建一个测试用例。
具体请参考 文档 。
举个例:
import unittestdef fun(x): return x + 1 class MyTest(unittest.TestCase): def test(self): self.assertEqual(fun(3), 4)
执行后成功。
但是,如果将期望的结果改成5,则执行的结果如下图所示:
2.2 Doctest
doctest 模块会搜索那些看起来像交互式会话的 Python 代码片段,然后尝试执行并验证结果.即使从没接触过 doctest,我们也可以从这个名字中窥到一丝端倪。“它看起来就像代码里的文档字符串(docstring)一样” 如果你这么想的话,就已经对了一半了。
举个例子:
def square(x):"""Squares x. >>> square(2) 4 >>> square(-2) 4 >>> square(5) 25 """ return x * x if __name__ == '__main__': import doctest doctest.testmod()
当执行该代码后,会执行文档内>>> 后面的测试代码,并与下一行的结果进行比对。执行的结果如下:
但是,如果我们把结果改一下,square(2)的结果改成5,测试代码如下:
def square(x):"""Squares x. >>> square(2) 5 >>> square(-2) 4 >>> square(5) 25 """ return x * x if __name__ == '__main__': import doctest doctest.testmod()
执行的测试结果如下所示:
2.3 py.test
py.test是unittest的替代工具。
尽管它是一个功能丰富、灵活的测试框架,但是它的语法很简单。创建一个单元测试就像编写一个模块一样。相比unittest,实现相同的测试功能,py.test做的事情更少。
py.test详细 文档 。
首先,安装py.test
pip install pytest
第二步,编写测试代码
def func(x):return x + 1 def test_answer(): assert func(3) == 5
第三步,执行测试代码。
- 找到pytest安装路径。
- 用其所在的解析器(python.exe)执行test.py ,执行命令比如:
执行的结果如下图所示:
2.4 Nose
Nose是对unittest的扩展,使得python的测试更加简单。nose自动发现测试代码并执行,nose提供了大量的插件,比如测试输出的xUnitcompatible,覆盖报表等等。
nose的详细文档: https://nose.readthedocs.org/en/latest/
注意:nose本身是支持python3的,但是很多它的插件不支持。
2.5 tox
最大的特色,是自动最测试环境的管理以及使用多个解析器配置进行测试。
tox的详细文档: http://testrun.org/tox/latest/
2.6 Unittest2
是unitest的升级版。对API进行了改善以及更好的诊断语法。
unittest2的详细文档: https://pypi.python.org/pypi/unittest2
首先,安装
pip install unittest2
为了以后能在unittest与unittest2之间进行切换,最好的代码编写方式如下:
import unittest2 as unittest class MyTest(unittest.TestCase): ...
2.7 mock unittest.mock是用来测试python的库。在python3.3版本以后,这个是一个标准库。 对老版本来说,使用pip install mock 进行安装。
mock的精髓在于,你可以使用模拟的对象来替代你的系统的一部分,然后验证后续的执行是否正确。
mock的详细文档:http://www.voidspace.org.uk/python/mock/
UNiTTEST
Pyhon工作原理—— 核心概念:test case, testsuite, TestLoder,TextTestRunner,TextTestResult, test fixture
TestCase(测试用例): 所有测试用例的基类,它是软件 测试中最基本的组成单元。
一个test case就是一个测试用例,是一个完整的测试流程,包括测试前环境的搭建setUp,执行测试代码(run),以及测试后环境的还原(tearDown)。测试用例是一个完整的测试单元,可以对某一问题进行验证。
TestSuite(测试套件):多个测试用例test case集合就是TestSuite,TestSuite可以嵌套TestSuite
TestLoder:是用来加载 TestCase到TestSuite中,其中有几个loadTestsFrom_()方法,就是从各个地方寻找TestCase,创建他们的实例,然后add到TestSuite中,再返回一个TestSuite实例
TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
TextTestResult:测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息
TestFixture:又叫测试脚手,测试代码的运行环境,指测试准备前和执行后要做的工作,包括setUp和tearDown方法
二、测试流程:
1. 写好TestCase:一个class继承unittest.TestCase,就是一个测试测试用例,其中有多个以test开头的方法,那么 每一个这样的,在load的时候会生成一个TestCase实例。如果一个class中有四个test开头的方法,最后load到suite中时则有四个测试用例
2. 由TestLoder加载TestCase到TestSuite
3.然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中。
说明:a:通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者可以直接通过TextTestRunner来执行用例
b:Runner执行时,默认将结果输出到控制台,我们可以设置其输出到文件,在文件中查看 结果,也可以通过HTMLTestRunner将结果输出到HTML)
下面写一个简单的单元测试用例
![](/assets/blank.gif)
import unittestclass MyTest(unittest.TestCase): # 继承unittest.TestCasedef tearDown(self):# 每个测试用例执行之后做操作print('111')def setUp(self):# 每个测试用例执行之前做操作print('22222')@classmethoddef tearDownClass(self):# 必须使用 @ classmethod装饰器, 所有test运行完后运行一次print('4444444')@classmethoddef setUpClass(self):# 必须使用@classmethod 装饰器,所有test运行前运行一次print('33333')def test_a_run(self):self.assertEqual(1, 1) # 测试用例def test_b_run(self):self.assertEqual(2, 2) # 测试用例if __name__ == '__main__':unittest.main()#运行所有的测试用例
![](/assets/blank.gif)
下面是一些常用的断言,也就是校验结果
![](/assets/blank.gif)
assertEqual(a, b) a == b assertNotEqual(a, b) a != b assertTrue(x) bool(x) is True assertFalse(x) bool(x) is False assertIsNone(x) x is None assertIsNotNone(x) x is not None assertIn(a, b) a in b assertNotIn(a, b) a not in b
![](/assets/blank.gif)
那如何生成一个测试报告呢,需要加入另外一个模块了,HTMLTestRunner,这个模块需要自己安装,使用执行测试用例就会生成一个html的测试报告,里面会有每个测试用例的执行结果,代码如下:
![](/assets/blank.gif)
import HTMLTestRunner import unittestclass MyTest(unittest.TestCase):#继承unittest.TestCasedef tearDown(self):#每个测试用例执行之后做操作print('111')def setUp(self):#每个测试用例执行之前做操作print(22222)def test_run(self):# self.assertEqual(1,1)self.assertIs(1,1)#测试用例def test_run2(self):# self.assertEqual(1,1)self.assertIs(1,1)#测试用例def test_run3(self):# self.assertEqual(1,1)self.assertIs(1,1)#测试用例def test_run1(self):# self.assertEqual(1,1)self.assertIs(1,1)#测试用例if __name__ == '__main__':test_suite = unittest.TestSuite()#创建一个测试集合test_suite.addTest(MyTest('test_run1'))#测试套件中添加测试用例#test_suite.addTest(unittest.makeSuite(MyTest))#使用makeSuite方法添加所有的测试方法fp = open('res.html','wb')#打开一个保存结果的html文件runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='api测试报告',description='测试情况')#生成执行用例的对象runner.run(test_suite)#执行测试套件
![](/assets/blank.gif)
如果我们有很多个模块,每个模块下面都写了很多python文件,每个python文件里面都有测试用例,那怎么把这个目录下的用例都执行了呢,就要先找到这个目录下的所有python文件,然后找到里面的测试用例,逐个执行,代码如下:
![](/assets/blank.gif)
import unittest,HTMLTestRunnersuite = unittest.TestSuite()#创建测试套件all_cases = unittest.defaultTestLoader.discover('.','test_*.py')#找到某个目录下所有的以test开头的Python文件里面的测试用例for case in all_cases:suite.addTests(case)#把所有的测试用例添加进来fp = open('res.html','wb')runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='all_tests',description='所有测试情况')runner.run(suite)#运行测试
![](/assets/blank.gif)
我们在后续进行持续集成的时候,要让代码自动运行,就会用到Jenkins了,但是上面产生的测试报告都是html格式的,Jenkins不认识,就在Jenkins里面显示不出来。那咱们就要产生一些Jenkins认识的测试报告,Jenkins认识xml格式的报告,那咱们就产生xml格式的呗,就需要用一个新的模块,xmlrunner,安装直接 pip install xmlrunner即可,代码如下:
![](/assets/blank.gif)
import unittest import xmlrunner #导入这个模块 class My(unittest.TestCase):def test1(self,a,b,c):self.assertEqual(a+b,c)if __name__=='__main__':test_suite = unittest.TestSuite()test_suite.addTest(unittest.makeSuite(My))runner = xmlrunner.XMLTestRunner(output='report')#指定报告放的目录runner.run(test_suite)
![](/assets/blank.gif)
然后咱们运行,可以看到在report目录下已经产生了xml格式的报告了,而且还自动把日期加上了
转载于:https://www.cnblogs.com/klb561/p/9206286.html
Python单元测试框架——unittest相关推荐
- python单元测试框架—unittest
目录 unittest核心工作原理 unittest示例 示例1:简单示例 示例2:setUpClass()和tearDownClass() 示例3:通过在测试用例方法名中添加数字test_N指定执行 ...
- python单元测试框架Unittest详解
前言 我们今天来聊聊Python中的单元测试框架unittest,大家都知道在Python中比较热门的测试框架除了pytest就是unittest,我之前有讲过pytest所以今天想讲unittest ...
- python单元测试框架unittest介绍和使用_Python+Selenium框架设计篇之-简单介绍unittest单元测试框架...
前面文章已经简单介绍了一些关于自动化测试框架的介绍,知道了什么是自动化测试框架,主要有哪些特点,基本组成部分等.在继续介绍框架设计之前,我们先来学习一个工具,叫unittest. unittest是一 ...
- Python单元测试框架 unittest详解
一 整体结构概览 unittest原名为PyUnit,是由java的JUnit衍生而来.对于单元测试,需要设置预先条件,对比预期结果和实际结果. TestCase :通过继承TestCase类,我们可 ...
- python单元测试框架unittest介绍和使用_Python单元测试框架unittest简明使用实例
测试步骤1. 导入unittest模块 import unittest 2. 编写测试的类继承unittest.TestCase class Tester(unittest.TestCase) 3. ...
- Python单元测试及unittest框架用法实例解析
例题取用登录模块:代码如下 def login_check(username,password):''' 登录校验的函数:param username:账号:param password: 密码:re ...
- python写软件测试用例_Python单元测试框架unittest:单个测试用例编写步骤及实例...
一.Python单元测试框架的编写步骤 导入模块 必须继承unittest.TestCase 主要是配置环境:进行测试前的初始化工作,比如在接口测试前面做一些前置的参数赋值,数据库操作等等 定义测试用 ...
- python单元测试框架之unittest和pytest的区别
前言 今天呢笔者想和大家来聊聊Python单元测试框架,我们都知道python单元测试框架有很多,大家平时经常使用的是unittest,因为它比较基础,并且可以进行二次开发,如果你的开发水平很高,集成 ...
- Python单元测试框架Pyunit 的使用
Python单元测试框架Pyunit 使用示例: 1 import unittest 2 3 class Person: 4 def age(self): 5 return 34 6 def name ...
- 【整理】Python 单元测试框架 - PyUnit
1 概况 Python单元测试框架(The Python unit testing framework),简称为PyUnit, 是Kent Beck和Erich Gamma这两位聪明的家伙所设计JUn ...
最新文章
- Oracle迁移到MySQL性能下降的注意点
- java 打包工具_Java打包Windows安装程序
- C++标准库bitset类型(简单使用方法)
- 14. model(2)
- Android 设备上实现串口的移植
- 苹果appstore审核等待很长时间的解决方案
- 字幕制作:一键合并双语字幕(2019.1.30)附所有工具
- Openerp对象字段定义详解
- 怎么把ppt弄成链接的形式_ppt链接excle表格:如何在ppt中超级链接到指定的excel工作表...
- 派安盈Payoneer要年费吗?
- 买不起房的职场人,把装修欲转移到了工位
- Android从零开始搭建MVVM架构(4,android面试基础题记不住
- Java的socket连接以及string字符串长度过长解决
- EduCoder-程序设计技术R(第四部分循环结构程序设计1)- 第1关:小球自由落体运动
- 舆情监测平台都有哪些,舆情监测平台使用工作总结
- IAR安装与破解WIN7版本
- 《管理学》第三章 决策
- 计算机counta函数怎么用,counta函数的使用方法及实例 看完你就知道了
- PayPal提现被退回的解决办法?(教程和费用)
- 为啥GE云盒老显示服务器出现异常,ge云盒服务器出现异常
热门文章
- 汕尾php培训,系统发生错误
- nosql的base和cap_关系型数据库遵循ACID规则 NoSQL 数据库BASE CAP
- java http请求_零基础学Java,掌握Java基础难不难?
- 属于db模式缺点的是什么_DB与ES混合之应用系统场景分析探讨
- 线程+urllib下载互联网图片的一个示例
- poythoncode-实战4--读取文本文件,csv文件,存到系统中以大列表方式进行存储
- slf4j打印未捕获异常信息_谁再悄咪咪的吃掉异常,我上去就是一 JIO
- c语言如何输入未知数据类型的_C语言新手踩坑记!大坑小坑全部都是你的!
- 基于FaceNet人脸识别的人脸对比认证(一) -- 环境部署、认证实验
- java.util.concurrent.atomic.AtomicBoolean 源码