python单元测试unittest

一、单元测试、集成测试、功能测试

  1. 单元测试

    颗粒度最小,开发小组用白盒测试,测试单元是否符合‘设计’,对最小的单元进行检查和验证。

  2. 集成测试

    介于测试和系统测试之间,由开发小组用白盒+黑盒方法测试,即验证‘设计’又验证‘需求’。

  3. 功能测试颗粒度最大,由独立的测试小组采用黑盒测试,主要测试系统是否符合‘需求规格说明书’。

  4. 白盒测试与黑盒测试

    • 白盒测试:主要应用于单元测试阶段,主要是对代码级别的测试,针对程序内部的逻辑结构。
    • 黑盒测试:不考虑程序内部结构和逻辑结构,主要是测试系统的功能是否满足‘需求规格说明书’。一般会有一个输入值和输出值,和一个期望值做比较。

二、Unittest重要组成

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

unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunner

  1. TestFixtrue

    • 作用:用于一个测试环境的准备和销毁还原。

    • 功能:当测试用例每次执行之前需要准备测试环境,每次测试完成后还原测试环境,每次测试完成后还原测试环境,比如执行前连接数据库、打开浏览器等,执行完成后需要还原数据库、关闭浏览器等操作。这时候就可以启用testfixure

      1.setUp():准备环境,执行每个测试用例的前置条件;
      2.testDown():环境还原,执行每个测试用例的后置条件;
      3.setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只执行一次;
      4.testDownClass():必须使用@classmethod装饰器,所有case运行完后只执行一次;
      
  2. TestCase:测试用例

    • 定义:一个类class继承unittest.TestCase,就是一个测试用例。

    • 什么是测试用例?

      就是一个完整的测试流程,包括测试前准备环境的搭建,执行测试代码,以及测试后环境的还原。

    • 测试用例命名规则

      继承自unittest.TestCase的类中,测试方法的名称要以test开头。且值会执行以test开头定义的方法,测试用例执行的顺序会按照方法的ASCII值排序。

      如果想跳过某个测试用例,需要添加@unittest.skip

  3. TestSuite

    测试套件,可以将多个测试用例集合在一起,能一起执行选中的测试用例

    suite = unittest.TestSuite()#创建测试套件
    case_list = [“test1”,”test2”….]
    For case in case_list:
        suite.addTest(类名(case))
    
  4. TextRunner

    执行测试用例

    通过TestRunner类提供的run()方法来执行test suite/test cas

    格式

    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)
    

三、断言

常用:assertEqual(a,b):断言a和b是否相等,相等则测试用例通过。

  • 实际测试案例-主要测试一个代码块

    1. 测试代码和开发是分开的

    2. Calculate.py代码

      class Caculate():
          def add(self, a, b):
              c = a + b
              return c
          def reduce(self, a, b):
              c = a - b
              return c
      
    3. testdemotwo.py代码

      import unittest
      from dev.Caculate import Caculate
      c = Caculate()
      add = c.add(1, 4)
      reduce = c.reduce(4, 1)
      class UnitTestTwo(unittest.TestCase):
          def setUp(self) -> None:
              print("开始")
          def test001(self):
              self.assertEqual(add, 5)
          def test002(self):
              self.assertEqual(reduce, 3)
          def tearDown(self) -> None:
              print("结束")
      if __name__ == '__main__':
          unittest.main
      

四、生成测试报告

html格式的就是HTMLTestRunner啦,HTMLTestRunner是python标准库的unittest框架的一个扩展,它可以生成一个直观清晰的HTML测试报告。

  1. 下载HTMLTestRunner.py复制到项目中

  2. 格式

    with open("../report.html","wb") as f:
                HTMLTestRunner(
                    stream=f,
               title="单元测试",
                    description="测试一期",
                    verbosity=2
                ).run(suite)   
    
  3. 创建一个类,testhtml

  4. 生成测试报告

五、操作

1:导入unittest模块   >>>import unittest
2:编写一个类继承unittest.TestCase
3:调用setUp(self), tearDown(self)方法实现测试用例前后阶段的操作
4:编写测试用例方法
    (1)该方法必须以test开头,否则在unittest.main()中调用测试找不到该方法
    (2)设置断言进行判断,输入数据和输出数据的预期结果
5:创建套件,将多个测试用例存放套件中,一并执行()
6:生成测试报告(python自带或者导入HTMLTestRunner生成html格式的测试报告)
7:运行测试用例unittest.main(),调用测试用例中以test开头的方法

六、读取文件

  1. 读取xml文件

  2. 创建xml文件

    开头结束

    可自定义标签

  3. 读取xml文件

    from xml.dom import minidom
    class Readxml():
        def read_xml(self,filename,onename,twoname):
            root =minidom.parse(filename)
            firstnode =root.getElementsByTagName(onename)[0]
            secondnode=firstnode.getElementsByTagName(twoname)[0].firstChild.data
            return secondnode
    
    1. 获取xml固定简单数据

      firstnode = root.getElementsByTagName('add')[0]
              secondnode = firstnode.getElementsByTagName('add2')[0].firstChild.data
      
    2. 抽取方法

      from xml.dom import minidom
      class Readxml():
          def readXml(self,filename,onename,twoname):
              root = minidom.parse(filename)
      
              firstnode = root.getElementsByTagName(onename)[0]
              secondnode = firstnode.getElementsByTagName(twoname)[0].firstChild.data
              return secondnode
      
    3. 具体使用

      import unittest
      from unittest1.dev.Caculate import Caculate
      from unittest1.testdate.xmltest import Readxml
      from unittest1.testdate.testcsv import ReadCsv
      
      c = Caculate()
      r = Readxml()
      
      a1 = r.readXml('../testdate/xmldata.xml','add','add1')
      a2 = r.readXml('../testdate/xmldata.xml','add','add2')
      a3 = r.readXml('../testdate/xmldata.xml','add','add3')
      
      r1 = r.readXml('../testdate/xmldata.xml','reduce','reduce1')
      r2 = r.readXml('../testdate/xmldata.xml','reduce','reduce2')
      r3 = r.readXml('../testdate/xmldata.xml','reduce','reduce3')
      
      class UnitTest(unittest.TestCase):
          def setUp(self) -> None:
              print('开始测试环境')
      
          def testAdd(self):
              # sum = c.add(int(a1),int(a2))
              # self.assertEqual(sum,int(a3))
              
          def testReduce(self):
              # dif = c.reduce(int(r1),int(r2))
              # self.assertEqual(dif,int(r3))
      
          def tearDown(self) -> None:
              print('还原测试环境')
      if __name__ == '__main__':
           suite = unittest.TestSuite()
           caseList = ['testAdd','testReduce']
           for case in caseList:
               suite.addTest(UnitTest(case))
      
           runner = unittest.TextTestRunner(verbosity=2)
           runner.run(suite)
      
      
  4. 读取csv文件

    1. 在data下创建CSV文件a.csv

    2. 创建读文件的文件:testcsv.py

      import csv
      
      class ReadCsv():
          def Read_csv(self,*kwaegs):
              itme = []
              c = csv.reader(open('../testdate/caculate.csv','r'))
              for csv_i in c:
                  a = []
                  for i in csv_i:
                      i = int(i)
                      a.append(i)
                  itme.append(a)
              return itme
      
      #
      # r = ReadCsv()
      # print(r.Read_csv())
      
    3. 在测试用例的类中

完整代码

import unittest
from unittest1.dev.Caculate import Caculate
from unittest1.testdate.xmltest import Readxml
from unittest1.testdate.testcsv import ReadCsv

c = Caculate()
r = ReadCsv()
aa = r.Read_csv()
print(aa)


# r = Readxml()
#
# a1 = r.readXml('../testdate/xmldata.xml','add','add1')
# a2 = r.readXml('../testdate/xmldata.xml','add','add2')
# a3 = r.readXml('../testdate/xmldata.xml','add','add3')
#
# r1 = r.readXml('../testdate/xmldata.xml','reduce','reduce1')
# r2 = r.readXml('../testdate/xmldata.xml','reduce','reduce2')
# r3 = r.readXml('../testdate/xmldata.xml','reduce','reduce3')

class UnitTest(unittest.TestCase):
    def setUp(self) -> None:
        print('开始测试环境')

    def testAdd(self):
        # sum = c.add(int(a1),int(a2))
        # self.assertEqual(sum,int(a3))
        add = c.add(aa[0][0],aa[0][1])
        self.assertEqual(add,aa[0][2])

    def testReduce(self):

        reduce = c.reduce(aa[1][0],aa[1][1])
        self.assertEqual(reduce,aa[1][2])
        # dif = c.reduce(int(r1),int(r2))
        # self.assertEqual(dif,int(r3))

    def tearDown(self) -> None:
        print('还原测试环境')


# if __name__ == '__main__':
#
#     suite = unittest.TestSuite()
#     caseList = ['testAdd','testReduce']
#     for case in caseList:
#         suite.addTest(UnitTest(case))
#
#     runner = unittest.TextTestRunner(verbosity=2)
#     runner.run(suite)

你可能感兴趣的:(python单元测试unittest)