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

yipeiwu_com6年前Python基础

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全部的属性和方法,他们的关系如下图所示。

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设计】。

相关文章

使用Python编写Linux系统守护进程实例

守护进程(daemon)是指在UNIX或其他多任务操作系统中在后台执行的电脑程序,并不会接受电脑用户的直接操控。此类程序会被以进程的形式初始化。通常,守护进程没有任何存在的父进程(即PP...

python Flask 装饰器顺序问题解决

上周 RealWorld CTF 2018 web 题 bookhub 有个未授权访问的漏洞,比较有意思,赛后看了一下公开的 WriteUp,大家也都没写清楚,所以就有了这篇博文。 前言...

python+selenium实现京东自动登录及秒杀功能

本文实例为大家分享了selenium+python京东自动登录及秒杀的代码,供大家参考,具体内容如下 运行环境: python 2.7 python安装selenium 安装webdr...

python 监测内存和cpu的使用率实例

我就废话不多说了,直接上代码吧! import paramiko import pymysql import time linux = ['192.168.0.179'] def...

跟老齐学Python之永远强大的函数

跟老齐学Python之永远强大的函数

函数,对于人类来讲,能够发展到这个数学思维层次,是一个飞跃。可以说,它的提出,直接加快了现代科技和社会的发展,不论是现代的任何科技门类,乃至于经济学、政治学、社会学等,都已经普遍使用函数...