Python单元测试框架之unittest+requests+ddt+excel接口自动化测试
unitetest是python里單元測(cè)試框架,是基于 java 的 junit 測(cè)試框架?相當(dāng)于是一個(gè) python 版的 junit,除了 unittest,還有一個(gè) pytest 框架
unittest.TestCase:TestCase類,所有測(cè)試用例類繼承的基本類
一個(gè)TestCase的實(shí)例就是一個(gè)測(cè)試用例。一個(gè)測(cè)試用例要包括測(cè)試前準(zhǔn)備環(huán)境的搭建(setUp),執(zhí)行測(cè)試代碼(run),以及測(cè)試后環(huán)境的還原(tearDown)。一個(gè)測(cè)試用例是一個(gè)完整的測(cè)試單元,通過(guò)運(yùn)行這個(gè)測(cè)試單元,可以對(duì)某一個(gè)功能進(jìn)行驗(yàn)證
?
unittest.main():使用她可以方便的將一個(gè)單元測(cè)試模塊變?yōu)榭芍苯舆\(yùn)行的測(cè)試腳本,main()方法使用TestLoader類來(lái)搜索所有包含在該模塊中以“test”命名開(kāi)頭的測(cè)試方法,并自動(dòng)執(zhí)行他們。執(zhí)行方法的默認(rèn)順序是:根據(jù)ASCII碼的順序加載測(cè)試用例,數(shù)字與字母的順序?yàn)?#xff1a;0-9,A-Z,a-z。所以以A開(kāi)頭的測(cè)試用例方法會(huì)優(yōu)先執(zhí)行,以a開(kāi)頭會(huì)后執(zhí)行
?
一、setUp()和tearDown()函數(shù)
? ? setUp()函數(shù)是在眾多函數(shù)或說(shuō)是在一個(gè)類里最先被調(diào)用的函數(shù),每執(zhí)行完一個(gè)函數(shù)都要從setUp()調(diào)用開(kāi)始后再執(zhí)行下一個(gè)函數(shù),有幾個(gè)函數(shù)幾次,與位置無(wú)關(guān),隨便放在那里都是他先被調(diào)用。
? ? ?tearDown()函數(shù)是在眾多函數(shù)執(zhí)行完后他才被執(zhí)行,不管這個(gè)類里面有多少函數(shù),他總是最后一個(gè)被執(zhí)行,與位置無(wú)關(guān),放在那里都行,最后不管測(cè)試函數(shù)是否執(zhí)行成功都執(zhí)行tearDown()方法;如果setUp()方法失敗,則認(rèn)為這個(gè)測(cè)試項(xiàng)目失敗,不會(huì)執(zhí)行測(cè)試函數(shù)也不執(zhí)行tearDown()方法。
1、setUp()和tearDown()方法都是非必要條件,如果沒(méi)有也可以寫(xiě)pass
2、setUp()和tearDown()方法每個(gè)測(cè)試用例都會(huì)執(zhí)行,先執(zhí)行前置setUp,然后執(zhí)行的用例(test*),最后執(zhí)行的后置tearDown
3、setUp():setUp()方法用于測(cè)試用例執(zhí)行前初始化工作。如測(cè)試用例中需要訪問(wèn)數(shù)據(jù)庫(kù),可以在setUp中建立數(shù)據(jù)庫(kù)連接并進(jìn)行初始化。如測(cè)試用例需要登錄web,可以先實(shí)例化瀏覽器
4、tearDown():tearDown()方法用于測(cè)試用例執(zhí)行之后的善后工作。如關(guān)閉數(shù)據(jù)庫(kù)連接、關(guān)閉瀏覽器
5、未加裝飾器,先執(zhí)行前置setUp,再執(zhí)行test開(kāi)頭的test01,最后執(zhí)行后置tearDown,繼續(xù)循環(huán)所有用例;加了裝飾器@classmethod,先執(zhí)行setUp,再執(zhí)行test開(kāi)頭的所有用例,最后執(zhí)行tearDown
#未加裝飾器,先執(zhí)行前置setUp,再執(zhí)行test開(kāi)頭的測(cè)試用例,最后執(zhí)行后置tearDown,繼續(xù)循環(huán)所有用例import unittest class Test(unittest.TestCase): #繼承unittest.TestCase這個(gè)類def setUp(self): #測(cè)試用例執(zhí)行前運(yùn)行print('setUp__')def tearDown(self): #測(cè)試用例結(jié)束后運(yùn)行print('tearDown')def testMinus(self): #測(cè)試用例名稱以test開(kāi)頭'''這里是減法'''print('這里是減法') result=6-5 hope=1 self.assertEqual(result,hope) def testDivide(self): '''這里是除法'''print('這里是除法')result=7/2hope=3.5self.assertEqual(result,hope) if __name__ == '__main__':unittest.main()C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py setUp__ 這里是除法 tearDown setUp__ 這里是減法 tearDown .. ---------------------------------------------------------------------- Ran 2 tests in 0.000sOKProcess finished with exit code 0 #加了裝飾器@classmethod,先執(zhí)行setUp,再執(zhí)行test開(kāi)頭的所有用例,最后執(zhí)行tearDownimport unittest class Test(unittest.TestCase): @classmethod def setUpClass(cls): print('setUp__') @classmethod def tearDownClass(cls): print('tearDown') def test_003(self): ''這里是test_003''' print('這里是減法') result=6-5 hope=1 self.assertEqual(result,hope) def test_004(self): ''這里是test_004''' print('這里是除法') result=7/2 hope=3.5 self.assertEqual(result,hope) if __name__ == '__main__': unittest.main() C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py setUp__ .. 這里是減法 這里是除法 tearDown ---------------------------------------------------------------------- Ran 2 tests in 0.001sOKProcess finished with exit code 0?
二、unittest.defaultTestLoader(): defaultTestLoader()類
通過(guò)該類下discover()方法將測(cè)試目錄匹配查找測(cè)試用例文件(test*.py),將查找的測(cè)試用例組裝到測(cè)試套件TestSuite,再返回一個(gè)TestSuite實(shí)例,因此可以直接通過(guò)run()方法執(zhí)行discover
discover方法來(lái)加載用例,discover加載到的用例是一個(gè)list集合,需要重新寫(xiě)入到一個(gè)list對(duì)象testcase里,用TextTestRunner這里類的run方法去執(zhí)行,discover方法里面有三個(gè)參數(shù):
case_dir:這個(gè)是待執(zhí)行用例的目錄
pattern:這個(gè)是匹配腳本名稱的規(guī)則,test*.py意思是匹配test開(kāi)頭的所有腳本。
top_level_dir:這個(gè)是頂層目錄的名稱,一般默認(rèn)等于None就行了
# 測(cè)試用例路徑(當(dāng)前文件目錄) case_path = os.path.dirname(os.path.realpath(__file__)) #加載test.py文件,TestCase到TestSuite集合中,返回一個(gè)TestSuite實(shí)例 discover = unittest.defaultTestLoader.discover(case_path, pattern="test.py", top_level_dir=None) print(discover) <unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test.Test testMethod=test01>, <test.Test testMethod=test02>]>]>]> class Test(unittest.TestCase):def setUp(self):print('數(shù)據(jù)準(zhǔn)備階段')def tearDown(self):print('數(shù)據(jù)清理結(jié)束')def test01(self):print('輸出test01')def test02(self):print('輸出test02') if __name__=='__main__':# 測(cè)試用例路徑case_path = os.path.dirname(os.path.realpath(__file__))#加載test.py文件,TestCase到TestSuite集合中,返回一個(gè)TestSuite實(shí)例discover = unittest.defaultTestLoader.discover(case_path, pattern="test.py", top_level_dir=None)print(discover)#實(shí)例化runnerrunner=unittest.TextTestRunner()#調(diào)用實(shí)例run方法runner.run(discover)C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py .. <unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test.Test testMethod=test01>, <test.Test testMethod=test02>]>]>]> ---------------------------------------------------------------------- 數(shù)據(jù)準(zhǔn)備階段 Ran 2 tests in 0.001s 輸出test01數(shù)據(jù)清理結(jié)束 OK 數(shù)據(jù)準(zhǔn)備階段 輸出test02 數(shù)據(jù)清理結(jié)束Process finished with exit code 0 ?三、unittest.TestSuite():unittest框架的TestSuite()類
用來(lái)創(chuàng)建測(cè)試套件,多個(gè)測(cè)試用例test case集合就是TestSuite,TestSuite可以嵌套TestSuite
對(duì)于某一個(gè)功能模塊的驗(yàn)證可能需要多個(gè)測(cè)試用例,多個(gè)測(cè)試用例集合在一起執(zhí)行驗(yàn)證某一個(gè)功能,這樣就是一個(gè)TestSuite。通過(guò)addTest()方法將 TestCase 加載到 TestSuite()中,最終將傳遞給testRunner進(jìn)行測(cè)試執(zhí)行
?
四、unittest.TextTestRunner():unittest框架的TextTestRunner()類
通過(guò)該類下面的run()方法來(lái)運(yùn)行suite所組裝的測(cè)試用例,入?yún)閟uite測(cè)試套件
runner=unittest.TextTestRunner()
runner.run(all_case())
class Test(unittest.TestCase):def setUp(self):print('數(shù)據(jù)準(zhǔn)備階段')def tearDown(self):print('數(shù)據(jù)清理結(jié)束')def test01(self):print('輸出test01')def test02(self):print('輸出test02') if __name__=='__main__':# 測(cè)試用例路徑case_path = os.path.dirname(os.path.realpath(__file__))#加載test.py文件,TestCase到TestSuite集合中,返回一個(gè)TestSuite實(shí)例discover = unittest.defaultTestLoader.discover(case_path, pattern="test.py", top_level_dir=None)print(discover)#實(shí)例化runnerrunner=unittest.TextTestRunner()#調(diào)用實(shí)例run方法runner.run(discover)C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py .. <unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test.Test testMethod=test01>, <test.Test testMethod=test02>]>]>]> ---------------------------------------------------------------------- 數(shù)據(jù)準(zhǔn)備階段 Ran 2 tests in 0.001s 輸出test01數(shù)據(jù)清理結(jié)束 OK 數(shù)據(jù)準(zhǔn)備階段 輸出test02 數(shù)據(jù)清理結(jié)束Process finished with exit code 0?
五、生成html報(bào)告,report_path是存放測(cè)試報(bào)告的地址
stream:測(cè)試報(bào)告寫(xiě)入文件的存儲(chǔ)區(qū)域
title:測(cè)試報(bào)告的主題
description:測(cè)試報(bào)告的描述
?
#實(shí)例化runner runner=unittest.TextTestRunner()#測(cè)試報(bào)告存放地址 report_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"result.html") #打開(kāi) fp = open(report_path, "wb") #寫(xiě)入 runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title="自動(dòng)化測(cè)試報(bào)告",description="用例執(zhí)行情況:") #調(diào)用實(shí)例run方法 runner.run(discover) #關(guān)閉 fp.close() import unittest,os import HTMLTestRunner class Test(unittest.TestCase):def setUp(self):print('setup數(shù)據(jù)準(zhǔn)備階段——————')def tearDown(self):print('teardown數(shù)據(jù)清理收尾階段————')def test01(self):print('執(zhí)行test01測(cè)試用例')def test02(self):print('執(zhí)行test02測(cè)試用例') if __name__=='__main__':#測(cè)試用例路徑case_path = os.path.dirname(os.path.realpath(__file__))#加載test.py文件,TestCase到TestSuite集合中,返回一個(gè)TestSuite實(shí)例discover = unittest.defaultTestLoader.discover(case_path, pattern="test.py", top_level_dir=None)print(discover)#實(shí)例化runnerrunner=unittest.TextTestRunner()#測(cè)試報(bào)告存放地址report_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"result.html")#打開(kāi)fp = open(report_path, "wb")#寫(xiě)入runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title="自動(dòng)化測(cè)試報(bào)告",description="用例執(zhí)行情況:")#調(diào)用實(shí)例run方法runner.run(discover)#關(guān)閉fp.close()C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py .. setup數(shù)據(jù)準(zhǔn)備階段—————— 執(zhí)行test01測(cè)試用例 ---------------------------------------------------------------------- teardown數(shù)據(jù)清理收尾階段———— Ran 2 tests in 0.002s setup數(shù)據(jù)準(zhǔn)備階段——————執(zhí)行test02測(cè)試用例 OK teardown數(shù)據(jù)清理收尾階段————Process finished with exit code 0C:\Users\wangli\PycharmProjects\AutoMation\venv\Scripts\python.exe C:/Users/wangli/PycharmProjects/AutoMation/case/test.py ..<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test.Test testMethod=test01>, <test.Test testMethod=test02>]>]>]> <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> Time Elapsed: 0:00:00.001000Process finished with exit code 0 參考代碼# coding:utf-8 import unittest import os import HTMLTestRunner# python2.7要是報(bào)編碼問(wèn)題,就加這三行,python3不用加import sys reload(sys) sys.setdefaultencoding('utf8')# 用例路徑 case_path = os.path.join(os.getcwd(), "case") # 報(bào)告存放路徑 report_path = os.path.join(os.getcwd(), "report") def all_case():discover = unittest.defaultTestLoader.discover(case_path,pattern="test*.py",top_level_dir=None)print(discover)return discoverif __name__ == "__main__":# runner = unittest.TextTestRunner()# runner.run(all_case())# html報(bào)告文件路徑report_abspath = os.path.join(report_path, "result.html")fp = open(report_abspath, "wb")runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'自動(dòng)化測(cè)試報(bào)告,測(cè)試結(jié)果如下:',description=u'用例執(zhí)行情況:')# 調(diào)用add_case函數(shù)返回值runner.run(all_case())fp.close()?
六、unittest.skip():裝飾器
當(dāng)運(yùn)行用例時(shí),有些用例可能不想執(zhí)行等,可用裝飾器暫時(shí)屏蔽該條測(cè)試用例。一種常見(jiàn)的用法就是比如說(shuō)想調(diào)試某一個(gè)測(cè)試用例,想先屏蔽其他用例就可以用裝飾器屏蔽
@unittest.skip(reason): skip(reason)裝飾器:無(wú)條件跳過(guò)裝飾的測(cè)試,并說(shuō)明跳過(guò)測(cè)試的原因
@unittest.skipIf(reason): skipIf(condition,reason)裝飾器:條件為真時(shí),跳過(guò)裝飾的測(cè)試,并說(shuō)明跳過(guò)測(cè)試的原因
@unittest.skipUnless(reason): skipUnless(condition,reason)裝飾器:條件為假時(shí),跳過(guò)裝飾的測(cè)試,并說(shuō)明跳過(guò)測(cè)試的原因。
@unittest.expectedFailure(): expectedFailure()測(cè)試標(biāo)記為失敗
?
?
七、斷言
assertEqual(self, first, second, msg="失敗原因")?
unittest 常用的斷言方法?
1.assertEqual(self, first, second, msg=None)?
--判斷兩個(gè)參數(shù)相等:first == second?
2.assertNotEqual(self, first, second, msg=None)?
--判斷兩個(gè)參數(shù)不相等:first != second?
3.assertIn(self, member, container, msg=None)?
--判斷是字符串是否包含:member in container?
4.assertNotIn(self, member, container, msg=None)?
--判斷是字符串是否不包含:member not in container?
5.assertTrue(self, expr, msg=None)?
--判斷是否為真:expr is True?
6.assertFalse(self, expr, msg=None)?
--判斷是否為假:expr is False?
7.assertIsNone(self, obj, msg=None)?
--判斷是否為 None:obj is None?
8.assertIsNotNone(self, obj, msg=None) --判斷是否不為 None:obj is not None?
?
?
?
八、數(shù)據(jù)驅(qū)動(dòng)DDT
?
?
總結(jié)
以上是生活随笔為你收集整理的Python单元测试框架之unittest+requests+ddt+excel接口自动化测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pycharm+pyqt5配置
- 下一篇: 1g等于多少mb计算机网络,手机流量1G