一、单元测试、集成测试、功能测试
-
单元测试
颗粒度最小,开发小组用白盒测试,测试单元是否符合‘设计’,对最小的单元进行检查和验证。
-
集成测试
介于测试和系统测试之间,由开发小组用白盒+黑盒方法测试,即验证‘设计’又验证‘需求’。
功能测试颗粒度最大,由独立的测试小组采用黑盒测试,主要测试系统是否符合‘需求规格说明书’。
-
白盒测试与黑盒测试
- 白盒测试:主要应用于单元测试阶段,主要是对代码级别的测试,针对程序内部的逻辑结构。
- 黑盒测试:不考虑程序内部结构和逻辑结构,主要是测试系统的功能是否满足‘需求规格说明书’。一般会有一个输入值和输出值,和一个期望值做比较。
二、Unittest重要组成
python中有自带的单元测试框架是unittest模块,用它做单元测试,它里面封装好了一些校验返回的结果方法(断言)和一些用了执行的初始化操作。
unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunner
-
TestFixtrue
作用:用于一个测试环境的准备和销毁还原。
-
功能:当测试用例每次执行之前需要准备测试环境,每次测试完成后还原测试环境,每次测试完成后还原测试环境,比如执行前连接数据库、打开浏览器等,执行完成后需要还原数据库、关闭浏览器等操作。这时候就可以启用testfixure
1.setUp():准备环境,执行每个测试用例的前置条件; 2.testDown():环境还原,执行每个测试用例的后置条件; 3.setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只执行一次; 4.testDownClass():必须使用@classmethod装饰器,所有case运行完后只执行一次;
-
TestCase:测试用例
定义:一个类class继承unittest.TestCase,就是一个测试用例。
-
什么是测试用例?
就是一个完整的测试流程,包括测试前准备环境的搭建,执行测试代码,以及测试后环境的还原。
-
测试用例命名规则
继承自unittest.TestCase的类中,测试方法的名称要以test开头。且值会执行以test开头定义的方法,测试用例执行的顺序会按照方法的ASCII值排序。
如果想跳过某个测试用例,需要添加@unittest.skip
-
TestSuite
测试套件,可以将多个测试用例集合在一起,能一起执行选中的测试用例
suite = unittest.TestSuite()#创建测试套件 case_list = [“test1”,”test2”….] For case in case_list: suite.addTest(类名(case))
-
TextRunner
执行测试用例
通过TestRunner类提供的run()方法来执行test suite/test cas
格式
runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
三、断言
常用:assertEqual(a,b):断言a和b是否相等,相等则测试用例通过。
-
实际测试案例-主要测试一个代码块
测试代码和开发是分开的
-
Calculate.py代码
class Caculate(): def add(self, a, b): c = a + b return c def reduce(self, a, b): c = a - b return c
-
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测试报告。
下载HTMLTestRunner.py复制到项目中
-
格式
with open("../report.html","wb") as f: HTMLTestRunner( stream=f, title="单元测试", description="测试一期", verbosity=2 ).run(suite)
创建一个类,testhtml
生成测试报告
五、操作
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开头的方法
六、读取文件
读取xml文件
-
创建xml文件
开头结束 可自定义标签
-
读取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
-
获取xml固定简单数据
firstnode = root.getElementsByTagName('add')[0] secondnode = firstnode.getElementsByTagName('add2')[0].firstChild.data
-
抽取方法
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
-
具体使用
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)
-
-
读取csv文件
在data下创建CSV文件a.csv
-
创建读文件的文件: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())
在测试用例的类中
完整代码
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)