Python单元测试unittest的具体使用示例


Posted in Python onDecember 17, 2018

Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作。

unittest是python的标准测试库,相比于其他测试框架是python目前使用最广的测试框架。

unittest有四个比较重要的概念是test fixture, test case, test suite, test runner, 。

在说unittest之前,先说几个概念:

TestCase 也就是测试用例

TestSuite 多个测试用例集合在一起,就是TestSuite

TestLoader是用来加载TestCase到TestSuite中的

TestRunner是来执行测试用例的,测试的结果会保存到TestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息

通过dir(unittest),我们可以看到unittest全部的属性和方法,他们的关系如下图所示。

Python单元测试unittest的具体使用示例

unittest主要类关系

正常调用unittest的流程是,TestLoader 自动将测试用例TestCase中加载到TestSuite里,TextTestRunner调用TestSuite的run方法,顺序执行里面的TestCase中以test开头的方法,并得到测试结果TestResult。在执行TestCase过程中,先进行SetUp()环境准备,执行测试代码,最后tearDown()进行测试的还原。

其中TestLoader在加载过程中,进行添加的TestCase是没有顺序的。一个TestCase里如果存在多个验证方法的话,会按照方法中test后方首字母的ascii码从小到大排序后执行。

可以通过手动调用TestSuite的addTest、addTests方法来动态添加TestCase,这样既可以确定添加用例的执行顺序,也可避免TestCase中的验证方法一定要用test开头。

下面写一个简单的单元测试用例

import unittest

class MyTest(unittest.TestCase): # 继承unittest.TestCase
  def tearDown(self):
    # 每个测试用例执行之后做操作
    print('111')

  def setUp(self):
    # 每个测试用例执行之前做操作
    print('22222')

  @classmethod
  def tearDownClass(self):
  # 必须使用 @ classmethod装饰器, 所有test运行完后运行一次
     print('4444444')
  @classmethod
  def 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()#运行所有的测试用例

下面是一些常用的断言,也就是校验结果

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

那如何生成一个测试报告呢,需要加入另外一个模块了,HTMLTestRunner,这个模块需要自己安装,使用执行测试用例就会生成一个html的测试报告,里面会有每个测试用例的执行结果,代码如下:

import HTMLTestRunner    
    import unittest
    class MyTest(unittest.TestCase):#继承unittest.TestCase
      def 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)
      #执行测试套件

如果我们有很多个模块,每个模块下面都写了很多python文件,每个python文件里面都有测试用例,那怎么把这个目录下的用例都执行了呢,就要先找到这个目录下的所有python文件,然后找到里面的测试用例,逐个执行,代码如下:

import unittest,HTMLTestRunner
    suite = 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)
    #运行测试

我们在后续进行持续集成的时候,要让代码自动运行,就会用到Jenkins了,但是上面产生的测试报告都是html格式的,Jenkins不认识,就在Jenkins里面显示不出来。那咱们就要产生一些Jenkins认识的测试报告,Jenkins认识xml格式的报告,那咱们就产生xml格式的呗,就需要用一个新的模块,xmlrunner,安装直接 pip install xmlrunner即可,代码如下:

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)

然后咱们运行,可以看到在report目录下已经产生了xml格式的报告了,而且还自动把日期加上了

Python单元测试unittest的具体使用示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python创建列表并给列表赋初始值的方法
Jul 28 Python
python删除本地夹里重复文件的方法
Nov 19 Python
Scrapy框架使用的基本知识
Oct 21 Python
对matplotlib改变colorbar位置和方向的方法详解
Dec 13 Python
详解Python使用Plotly绘图工具,绘制甘特图
Apr 02 Python
Python使用Pandas库实现MySQL数据库的读写
Jul 06 Python
python @propert装饰器使用方法原理解析
Dec 25 Python
Pytorch之finetune使用详解
Jan 18 Python
Selenium向iframe富文本框输入内容过程图解
Apr 10 Python
Tensorflow卷积实现原理+手写python代码实现卷积教程
May 22 Python
Python生成器传参数及返回值原理解析
Jul 22 Python
详解Django中views数据查询使用locals()函数进行优化
Aug 24 Python
Python使用Selenium爬取淘宝异步加载的数据方法
Dec 17 #Python
在scrapy中使用phantomJS实现异步爬取的方法
Dec 17 #Python
Python 通过调用接口获取公交信息的实例
Dec 17 #Python
python用插值法绘制平滑曲线
Feb 19 #Python
selenium在执行phantomjs的API并获取执行结果的方法
Dec 17 #Python
Python脚本完成post接口测试的实例
Dec 17 #Python
python:接口间数据传递与调用方法
Dec 17 #Python
You might like
php 静态变量的初始化
2009/11/15 PHP
php5.4以下版本json不支持不转义内容中文的解决方法
2015/01/13 PHP
PHP中使用BigMap实例
2015/03/30 PHP
编写PHP脚本过滤用户上传的图片
2015/07/03 PHP
PHP PDO和消息队列的个人理解与应用实例分析
2019/11/25 PHP
ThinkPHP5&5.1实现验证码的生成、使用及点击刷新功能示例
2020/02/07 PHP
JavaScript入门教程(8) Location地址对象
2009/01/31 Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
2011/10/31 Javascript
40款非常有用的 jQuery 插件推荐(系列一)
2011/12/21 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
javascript中apply和call方法的作用及区别说明
2014/02/14 Javascript
JavaScript关闭当前页面(窗口)不带任何提示
2014/03/26 Javascript
javascript去掉代码里面的注释
2015/07/24 Javascript
javascript正则表达式定义(语法)总结
2016/01/08 Javascript
Jquery判断form表单数据是否变化
2016/03/30 Javascript
使用 stylelint检查CSS_StyleLint
2016/04/28 Javascript
浅谈JavaScript的push(),pop(),concat()方法
2016/06/03 Javascript
Vue过滤器的用法和自定义过滤器使用
2017/02/08 Javascript
JS实现的邮箱提示补全效果示例
2018/01/30 Javascript
微信小程序实现列表页的点赞和取消点赞功能
2018/11/02 Javascript
详解vue更改头像功能实现
2019/04/28 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
关于vue组件事件属性穿透详解
2019/10/28 Javascript
Vue-CLI与Vuex使用方法实例分析
2020/01/06 Javascript
HTML5地理定位实例
2014/10/15 HTML / CSS
印尼购物网站:iLOTTE
2019/10/16 全球购物
LUISAVIAROMA中国官网:时尚奢侈品牌购物网站
2020/11/01 全球购物
物业客服专员岗位职责
2013/11/30 职场文书
制作部班长职位说明书
2014/02/26 职场文书
护士毕业实习感言
2014/03/05 职场文书
军训拉歌口号
2014/06/13 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
2015年挂职锻炼工作总结
2014/12/12 职场文书
个人工作能力自我评价
2015/03/05 职场文书
离婚起诉书怎么写
2015/05/19 职场文书
详细聊一聊mysql的树形结构存储以及查询
2022/04/05 MySQL