Python单元测试之unittest
生活随笔
收集整理的這篇文章主要介紹了
Python单元测试之unittest
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一:單元測試,集成測試,功能測試
單元測試
顆粒度最小,一般由開發小組采用白盒方式來測試,主要測試單元是否符合“設計”;是指對軟件中的最小可測試單元進行檢查和驗證集成測試
介于單元測試和系統測試之間,一般由開發小組采用白盒+黑盒的方法來測試,即驗證 “設計”又驗證“需求”。主要用來測試模板與模板之間的接口,同時還要測試一些主要 的業務功能。功能測試
顆粒度最大,一般由獨立的測試小組采用黑盒的方式來測試,主要測試系統是否符合 “需求規格說明書什么是白盒測試,什么是黑盒測試
白盒:主要應用于單元測試階段,主要是對代碼級別的測試,針對程序內部的邏輯結構。 測試的手段有:語句覆蓋、判定覆蓋、條件覆蓋、路徑覆蓋和條件組合覆蓋 黑盒: 不考慮程序內部結構和邏輯結構,主要是測試系統的功能是否滿足“需求規格說 明書”。一般會有一個輸入值和一個輸出值,和期望值做比較。二:Unittest重要組成
Python中有一個自帶的單元測試框架是unittest模塊,用它來做單元測試,它里面封 裝好了一些校驗返回的結果方法(斷言)和一些用例執行前的初始化操作。 unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunnerTestFixture
作用:
用于一個測試環境的準備和銷毀還原。功能:
當測試用例每次執行之前需要準備測試環境,每次測試完成后還原測試環境,比如執行 前連接數據庫、打開瀏覽器等,執行完成后需要還原數據庫、關閉瀏覽器等操作。這時 候就可以啟用testfixture主要方法:
setUp():準備環境,執行每個測試用例的前置條件; tearDown():環境還原,執行每個測試用例的后置條件; setUpClass():必須使用@classmethod裝飾器,所有case執行的前置條件,只運行 一次; tearDownClass():必須使用@classmethod裝飾器,所有case運行完后只運行一次;TestCase:測試用例
定義:
一個類class繼承 unittest.TestCase,就是一個測試用例什么是測試用例?
就是一個完整的測試流程,包括測試前準備環境的搭建(setUp),執行測試代碼(run), 以及測試后環境的還原(tearDown)。測試用例命名規則
繼承自unittest.TestCase的類中,測試方法的名稱要以test開頭。且只會執行以test開頭定義的方法(測試方法),測試用例執行的順序會按照方法名的ASCII值排序。如果想跳過某個測試用例,需要添加@unittest.skip)(‘描述信息')格式:
import unittest class Calc_testcase(unittest.TestCase):def setUp(self) : #測試用例方法執行前的操作print("start")def test1(self): #測試用例self.assertEqual(4,4)def tearDown(self) : #測試用例方法執行后的操作print("end") if __name__ =="__main__":unittest.main() #調用測試用例中以test開頭的方法
TestSuite
定義:
測試套件,可以將多個測試用例集合在一起,能一起執行選中的測試用例方法一:
#創建測試套件 suite = unittest.TestSuite() case_list = [“test1”,”test2”….] For case in case_list:suite.addTest(類名(case))方法二:
#創建測試套件 suite = unittest.TestSuite() suite.addTest(類名 (“test1“)) suite.addTest(類名 (“test2“))方法三:
#創建測試套件 suite = unittest.TestSuite() # 創建一個加載對象 loader = unittest.TestLoader() suite .addTest(loader.loadTestsFromTestCase(類名))TextRunner
執行測試用例通過TextTestRunner類提供的run()方法來執行test suite/test cas格式:
runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) verbosity :表示測試報告信息的詳細程度,一共三個值,默認是2三:斷言
驗證預期結果和實際結果
assertEqual(a,b):斷言a和b是否相等,相等則測試用例通過。 assertNotEqual(a,b):斷言a和b是否相等,不相等則測試用例通過。 assertTrue(x):斷言x是否True,是True則測試用例通過。 assertFalse(x):斷言x是否False,是False則測試用例通過。 assertIs(a,b):斷言a是否是b,是則測試用例通過。 assertNotIs(a,b):斷言a是否是b,不是則測試用例通過。 assertIsNone(x):斷言x是否None,是None則測試用例通過。 assertIsNotNone(x):斷言x是否None,不是None則測試用例通過。 assertIn(a,b):斷言a是否在b中,在b中則測試用例通過。 assertNotIn(a,b):斷言a是否在b中,不在b中則測試用例通過。 assertIsInstance(a,b):斷言a是是b的一個實例,是則測試用例通過。 assertNotIsInstance(a,b):斷言a是是b的一個實例,不是則測試用例通過。四:生成測試報告
html格式的就是HTMLTestRunner了,HTMLTestRunner是 Python 標準庫的 unittest 框架的一個擴展,它可以生成一個直觀清晰的 HTML 測試報告。使 用的前提就是要下載 HTMLTestRunner.py格式:
with open("../report.html","wb") as f:HTMLTestRunner(stream=f,title="單元測試",description="測試一期",verbosity=2).run(suite)
相關參數說明
六:代碼展示
對開發的代碼塊進行單元測試
開發被測代碼:
class Demo(object):def add(self,a,b):c=a+breturn cdef reduct(self,a,b):c=a-breturn c if __name__ == '__main__':d=Demo()d.add(5,6)d.reduct(10,6)print(d.add(5,6))print(d.reduct(10,6))單元測試代碼:
import unittest # 導入unittest包 from demo.demo1 import Demo # 將開發被測的代碼 導包過來 d=Demo() # 實例化開發的類 dd=d.add(5,2) # 調取相加的方法 ddd=d.reduct(10,5) # 調取相減的方法 class TestClass(unittest.TestCase): # unittest單元測試類必須繼承unittest.TestCasedef setUp(self) -> None:print('測試用例方法執行前的操作')def test01(self): # 測試用例必須test開頭self.assertEqual(7,dd) #斷言,預期結果和實際結果的對比def test02(self): # 測試用例必須test開頭self.assertEqual(5, ddd) #斷言,預期結果和實際結果的對比def tearDown(self) -> None: # 測試用例結束之后執行print('測試用例方法執行后的操作')@classmethod # case執行的前置條件,只運行一次def setUpClass(cls) -> None:print('所有case執行的前置條件,只運行一次')@classmethod # case運行完后只運行一次def tearDownClass(cls) -> None:print('所有case運行完后只運行一次') if __name__ == '__main__':# unittest.main()suite=unittest.TestSuite() # 創建測試套件case_list=['test01','test02'] # 定義一個列表for i in case_list: # 循環取值suite.addTest(TestClass(i)) # 添加到套件中run=unittest.TextTestRunner() # 執行測試用例run.run(suite)七:讀取文件
讀取xml文件
from xml.dom import minidom #導入xml模塊 class Readxml():def read_xml(self,filename,onename,twoname):root =minidom.parse(filename) # 文件路徑firstnode =root.getElementsByTagName(onename)[0] #xml取值secondnode=firstnode.getElementsByTagName(twoname) [0].firstChild.data #xml取值return secondnode讀取csv文件
import csv #導入csv模塊 class ReadCsv():def read_csv(self):item =[] #定義一個空列表c = csv.reader(open("../commonDemo/test1.csv","r")) #得到csv文件對象for csv_i in c:item.append(csv_i) #將獲取的數據添加到列表中return itemr = ReadCsv() print(r.read_csv())給大家的福利
案例:1:單元測試:測試開發的加減乘除函數傳遞兩個參數2:通過csv文件和xml文件讀取數據進行單元測試并生成html格式的測試報告第一種:xml文件讀取數據進行單元測試并生成html格式的測試報告
第一步:開發的代碼
class Demo(object):def add(self,a,b):c=a+breturn cdef reduct(self,a,b):c=a-breturn cdef cheng(self,a,b):c=a*breturn cdef chu(self,a,b):c=a/breturn c if __name__ == '__main__':d=Demo()d.add(5,6)d.reduct(10,6)d.cheng(2,3)d.chu(8,4)print(d.add(5,6))print(d.reduct(10,6))print(d.cheng(2,3))print(d.chu(8,4))第二步:創建一個xml文件
<note><add><add1>1</add1><add2>2</add2><add3>3</add3></add><reduct><reduct1>5</reduct1><reduct2>2</reduct2><reduct3>3</reduct3></reduct><cheng><cheng1>2</cheng1><cheng2>3</cheng2><cheng3>6</cheng3></cheng><chu><chu1>6</chu1><chu2>2</chu2><chu3>3</chu3></chu> </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.datareturn secondnode r = Readxml() print(r.read_xml("../data/test.xml","add","add1"))第四步:傳遞參數進行單元測試
import unittest from demo.demo_lianxi import Demo from readdata.readxml import Readxml r=Readxml() a1=r.read_xml('../data/test.xml','add','add1') a2=r.read_xml('../data/test.xml','add','add2') a3=r.read_xml('../data/test.xml','add','add3') r1=r.read_xml("../data/test.xml","reduct","reduct1") r2=r.read_xml("../data/test.xml","reduct","reduct2") r3=r.read_xml("../data/test.xml","reduct","reduct3") c1=r.read_xml('../data/test.xml','cheng','cheng1') c2=r.read_xml('../data/test.xml','cheng','cheng2') c3=r.read_xml('../data/test.xml','cheng','cheng3') chu1=r.read_xml('../data/test.xml','chu','chu1') chu2=r.read_xml('../data/test.xml','chu','chu2') chu3=r.read_xml('../data/test.xml','chu','chu3') d=Demo() aa=d.add(int(a1),int(a2)) rr=d.reduct(int(r1),int(r2)) cc=d.cheng(int(c1),int(c2)) chuchu=d.chu(int(chu1),int(chu2)) class CalcTestClass(unittest.TestCase):def setUp(self) -> None:print('start')def test01(self):self.assertEqual(int(a3),aa)def test02(self):self.assertEqual(int(r3),rr)def test03(self):self.assertEqual(int(c3),cc)def test04(self):self.assertEqual(int(chu3),chuchu)def tearDown(self) -> None:print('end') if __name__ == '__main__':unittest.main()第五步:生成html格式的測試報告
import unittest from data.HTMLTestRunner import HTMLTestRunner from test.testxml import CalcTestClassclass HtmlClass():def htmlmethod(self):suite=unittest.TestSuite()lists=['test01','test02','test03','test04']for i in lists:suite.addTest(CalcTestClass(i))with open('../response_xml.html','wb') as f:HTMLTestRunner(stream=f,title='加減乘除操作',description='測試開發代碼',verbosity=2).run(suite) h=HtmlClass() h.htmlmethod()結果展示:
第二種:csv文件讀取數據進行單元測試并生成html格式的測試報告
第一步:開發的代碼
class Demo(object):def add(self,a,b):c=a+breturn cdef reduct(self,a,b):c=a-breturn cdef cheng(self,a,b):c=a*breturn cdef chu(self,a,b):c=a/breturn c if __name__ == '__main__':d=Demo()d.add(5,6)d.reduct(10,6)d.cheng(2,3)d.chu(8,4)print(d.add(5,6))print(d.reduct(10,6))print(d.cheng(2,3))print(d.chu(8,4))第二步:
創建四個csv文件
3,2,5 7,3,4 2,3,6 8,2,4
第三步:讀取csv文件
第四步:傳遞參數進行單元測試
import unittest from demo.demo_lianxi import Demo from readdata.readcsv import ReadCsv r=ReadCsv() list1=r.add_csv() list2=r.reduct_csv() list3=r.cheng_csv() list4=r.chu_csv() d=Demo() class CalcTestClass(unittest.TestCase):def setUp(self) -> None:print('start')def test01(self):for i in list1:add1=d.add(int(i[0]),int(i[1]))print(i[0],i[1])self.assertEqual(add1,int(i[2]))def test02(self):for i in list2:reduct1 = d.reduct(int(i[0]), int(i[1]))print(i[0], i[1])self.assertEqual(reduct1, int(i[2]))def test03(self):for i in list3:cheng1 = d.cheng(int(i[0]), int(i[1]))print(i[0], i[1])self.assertEqual(cheng1, int(i[2]))def test04(self):for i in list4:chu1 = d.chu(int(i[0]), int(i[1]))print(i[0], i[1])self.assertEqual(chu1, int(i[2]))def tearDown(self) -> None:print('end') if __name__ == '__main__':unittest.main()第五步:生成html的測試報告
from test.testcsv import CalcTestClassclass HtmlClass():def htmlmethod(self):suite=unittest.TestSuite()lists=['test01','test02','test03','test04']for i in lists:suite.addTest(CalcTestClass(i))with open('../response_csv.html','wb') as f:HTMLTestRunner(stream=f,title='加減乘除操作',description='測試開發代碼',verbosity=2).run(suite) h=HtmlClass() h.htmlmethod()結果展示:
總結
以上是生活随笔為你收集整理的Python单元测试之unittest的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中面向对象的讲解(3)
- 下一篇: Python单元测试之pytest