一、單元測試、集成測試、功能測試
-
單元測試
顆粒度最小,開發小組用白盒測試,測試單元是否符合‘設計’,對最小的單元進行檢查和驗證。
-
集成測試
介于測試和系統測試之間,由開發小組用白盒+黑盒方法測試,即驗證‘設計’又驗證‘需求’。
功能測試顆粒度最大,由獨立的測試小組采用黑盒測試,主要測試系統是否符合‘需求規格說明書’。
-
白盒測試與黑盒測試
- 白盒測試:主要應用于單元測試階段,主要是對代碼級別的測試,針對程序內部的邏輯結構。
- 黑盒測試:不考慮程序內部結構和邏輯結構,主要是測試系統的功能是否滿足‘需求規格說明書’。一般會有一個輸入值和輸出值,和一個期望值做比較。
二、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文件
<note></note>開頭結束
可自定義標簽
-
讀取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)