电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

python自動化測試三部曲之unittest框架的實現(xiàn)

瀏覽:3日期:2022-07-09 08:41:14

終于等到十一,有時間寫博客了,準備利用十一這幾天的假期把這個系列的博客寫完

該系列文章本人準備寫三篇博客

第一篇:介紹python自動化測試框架unittest

第二篇:介紹django框架+request庫實現(xiàn)接口測試

第三篇:介紹利用Jenkins實現(xiàn)持續(xù)集成

今天進入第一篇,unittest框架介紹

一、unittest簡述

unittest是python語言的單元測試框架,在python的官方文檔中,對unittest單元測試框架進行了詳細的介紹,感興趣的讀者可以到https://www.python.org/doc

網(wǎng)站去了解;本篇博客重點介紹unittest單元測試框架在自動化測試中的應用

unittest單元測試框架提供了創(chuàng)建測試用例,測試套件,和批量執(zhí)行測試用例的方法,在python安裝成功后,unittest單元測試框架可以直接導入使用,他屬于python的標準庫;作為單元測試的框架,unittest單元測試框架也是對程序的最小模塊進行的一種敏捷化的測試。在自動化測試i中,我們雖然不需要做白盒測試,但是必須知道所使用語言的單元測試框架,這是因為后面我們測試,就會遇到用例組織的問題,雖然函數(shù)式編程和面向對象編程提供了對代碼的重構,但是對于所編寫的每個測試用例,不可能編寫成一個函數(shù)來調用執(zhí)行;利用單元測試框架,可以創(chuàng)建一個類,該類繼承unittest的TestCase,這樣可以把每個TestCase看成是一個最小的單元,由測試套件組織起來,運行時直接執(zhí)行即可,同時可引入測試報告。unittest各個組件的關系如果

TestCase------------------------------->TestFixture(測試固件)|||TestSuite(測試套件)----------------------->TestRunner(測試執(zhí)行)-------------------->TestReport(測試報告)

# TestCase# 類,必須要繼承unittest.TestCase# 一個類class繼承 unittest.TestCase,就是一個測試用例。一個TestCase的實例就是一個測試用例,就是一個完整的測試流程。# 包括測試前環(huán)境準備setUp()|setUpClass()、執(zhí)行代碼run()、測試環(huán)境后的還原tearDown()|tearDownClass()。# 繼承自unittest.TestCase的類中,測試方法的名稱要以test開頭。且只會執(zhí)行以test開頭定義的方法(測試用例)。

二、測試固件(TestFixture)

在unittest單元測試框架中,測試固件用于處理初始化的操作,例如,在對百度的搜索進行測試前,首先需要打開瀏覽器并且進入百度的首頁;測試結束后,需要關閉瀏覽器;測試固件提哦功能了兩種執(zhí)行形式,一種是每執(zhí)行一個測試用例,測試固件就會被執(zhí)行一次;另外一種就不管有多少個用例i,測試固件只會執(zhí)行一次

# 用于一個測試環(huán)境的準備和銷毀還原。# 當測試用例每次執(zhí)行之前需要準備測試環(huán)境,每次測試完成后還原測試環(huán)境,比如執(zhí)行前連接數(shù)據(jù)庫、打開瀏覽器等,執(zhí)行完成后需要還原數(shù)據(jù)庫、關閉瀏覽器等操作。# 這時候就可以啟用testfixture。# setUp():準備環(huán)境,執(zhí)行每個測試用例的前置條件;# tearDown():環(huán)境還原,執(zhí)行每個測試用例的后置條件;# setUpClass():必須使用@classmethod裝飾器,所有case執(zhí)行的前置條件,只運行一次;# tearDownClass():必須使用@classmethod裝飾器,所有case運行完后只運行一次;

1、測試固件每次均執(zhí)行

unittest單元測試框架提供了名為setUp的tearDown的測試固件。下面,我們通過編寫一個例子來看測試固件的執(zhí)行方式,測試代碼如下

import unittestclass Test1(unittest.TestCase): # 測試固件之前置條件 def setUp(self): print('這是前置條件') # 測試固件之后置條件 def tearDown(self): print('這是后置條件') def test_case1(self): print('test_case1') def test_case2(self): print('test_case2')if __name__ == ’__main__’: unittest.main(verbosity=2)

執(zhí)行結果如下

python自動化測試三部曲之unittest框架的實現(xiàn)

他的執(zhí)行順序是先執(zhí)行setUp方法,在執(zhí)行具體的用例,最后執(zhí)行tearDown方法

2、測試固件只執(zhí)行一次

鉤子方法setUp和tearDown雖然經(jīng)常使用,但是在自動化測試中,一個系統(tǒng)的測試用例多達上千條,每次都執(zhí)行一次的setUp和tearDown方法會耗費大量的性能,在unittest單元測試框架中還可以使用另外一種測試固件來解決這一問題,他就是setUpClass和tearDownClass方法,該測試固件方法是類方法,需要在方法上面加裝飾器@classmethod,使用該測試固件,不管有多少個用例,測試固件只執(zhí)行一次,具體代碼如下

import unittestclass Test1(unittest.TestCase): # def setUp(self): # print('這是前置條件') # # def tearDown(self): # print('這是后置條件') @classmethod def setUpClass(cls): print('這是類方法前置條件') @classmethod def tearDownClass(cls): print('這是類方法后置條件') def test_case1(self): print('test_case1') def test_case2(self): print('test_case2')if __name__ == ’__main__’: unittest.main(verbosity=2)

結果如下

python自動化測試三部曲之unittest框架的實現(xiàn)

3、兩種測試固件并存

import unittestclass Test1(unittest.TestCase): def setUp(self): print('這是前置條件') def tearDown(self): print('這是后置條件') @classmethod def setUpClass(cls): print('這是類方法前置條件') @classmethod def tearDownClass(cls): print('這是類方法后置條件') def test_case1(self): print('test_case1') def test_case2(self): print('test_case2')if __name__ == ’__main__’: unittest.main(verbosity=2)

執(zhí)行結果如下

python自動化測試三部曲之unittest框架的實現(xiàn)

結果表明,先執(zhí)行被@classmethod裝飾器裝飾的測試固件,在執(zhí)行普通的測試固件

三、測試執(zhí)行

在以上事例中,可以看到測試用例的執(zhí)行是在主函數(shù)中,unittest調用的是main,代碼如下,TestProjram還是一個類,再來看該類的構造函數(shù),代碼如下

main = TestProgram

TestProjram還是一個類,再來看該類的構造函數(shù),代碼如下

class TestProgram(object): '''A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. ''' # defaults for testing module=None verbosity = 1 failfast = catchbreak = buffer = progName = warnings = None _discovery_parser = None def __init__(self, module=’__main__’, defaultTest=None, argv=None, testRunner=None, testLoader=loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None, *, tb_locals=False): if isinstance(module, str): self.module = __import__(module) for part in module.split(’.’)[1:]:self.module = getattr(self.module, part) else: self.module = module if argv is None: argv = sys.argv self.exit = exit self.failfast = failfast self.catchbreak = catchbreak self.verbosity = verbosity self.buffer = buffer self.tb_locals = tb_locals if warnings is None and not sys.warnoptions: # even if DeprecationWarnings are ignored by default # print them anyway unless other warnings settings are # specified by the warnings arg or the -W python flag self.warnings = ’default’ else: # here self.warnings is set either to the value passed # to the warnings args or to None. # If the user didn’t pass a value self.warnings will # be None. This means that the behavior is unchanged # and depends on the values passed to -W. self.warnings = warnings self.defaultTest = defaultTest self.testRunner = testRunner self.testLoader = testLoader self.progName = os.path.basename(argv[0]) self.parseArgs(argv) self.runTests()

在unittest模塊中包含的main方法,可以方便的將測試模塊轉變?yōu)榭梢赃\行的測試腳本。main使用unittest.TestLoader類來自動查找和加載模塊內的測試用例,TestProgram類中的該部分的代碼如下

def createTests(self): if self.testNames is None: self.test = self.testLoader.loadTestsFromModule(self.module) else: self.test = self.testLoader.loadTestsFromNames(self.testNames, self.module)

在執(zhí)行測試用例時候,在main方法中加入了verbosity=2,代碼如下

if __name__ == ’__main__’: unittest.main(verbosity=2)

下面解釋一下verbosity部分,在verbosity中默認是1。0代表執(zhí)行的測試總數(shù)和全局結果,2代表詳細的信息

四、測試套件,TestSuite

# TestSuite# 上述簡單的測試會產(chǎn)生兩個問題,可不可以控制test測試用例的執(zhí)行順序?若不想執(zhí)行某個測試用例,有沒有辦法可以跳過?# 對于執(zhí)行順序,默認按照test的 A-Z、a-z的方法執(zhí)行。若要按自己編寫的用例的先后關系執(zhí)行,需要用到testSuite。# 把多個測試用例集合起來,一起執(zhí)行,就是testSuite。testsuite還可以包含testsuite。# 一般通過addTest()或者addTests()向suite中添加。case的執(zhí)行順序與添加到Suite中的順序是一致的。

1、直接執(zhí)行案例

我們在func.py這個文件中定義加減乘除4個測試函數(shù)

#Auther Bob#--*--conding:utf-8 --*--def add(a,b): return a + bdef minus(a,b): return a - bdef multi(a,b): return a * bdef divide(a,b): return a / b

python自動化測試三部曲之unittest框架的實現(xiàn)

然后在myunittest.py文件中定義我們的測試代碼,這里用到了斷言,我們后面會介紹

from test1 import funcclass Test2(unittest.TestCase): def setUp(self): print('前置條件') def tearDown(self): print('后置條件') def test_add(self): self.assertEqual(3,func.add(1,2)) def test_minus(self): self.assertEqual(4,func.minus(5,1)) def test_multi(self): self.assertEqual(4,func.multi(2,2)) def test_divide(self): self.assertEqual(10,func.divide(100,10))if __name__ == ’__main__’: unittest.main(verbosity=2)

執(zhí)行結果如下

python自動化測試三部曲之unittest框架的實現(xiàn)

2、添加案例到測試套件中

上述簡單的測試會產(chǎn)生兩個問題,可不可以控制test測試用例的執(zhí)行順序?若不想執(zhí)行某個測試用例,有沒有辦法可以跳過?對于執(zhí)行順序,默認按照test的 A-Z、a-z的方法執(zhí)行。若要按自己編寫的用例的先后關系執(zhí)行,需要用到testSuite。把多個測試用例集合起來,一起執(zhí)行,就是testSuite。testsuite還可以包含testsuite。一般通過addTest()或者addTests()向suite中添加。case的執(zhí)行順序與添加到Suite中的順序是一致的。

如果用到測試套件TestSuite,則需要先寫好測試代碼,但是先不要執(zhí)行

我們同樣在myunittest.py文件中定義我們的測試代碼

from test1 import funcclass Test3(unittest.TestCase): def setUp(self): print('前置條件') def tearDown(self): print('后置條件') def test_add(self): self.assertEqual(3,func.add(1,2)) def test_minus(self): self.assertEqual(4,func.minus(5,1)) def test_multi(self): self.assertEqual(4,func.multi(2,2)) def test_divide(self): self.assertEqual(10,func.divide(100,10))

我們在test_suit.py文件中引入測試案例,然后通過TestSuite類的addTests方法把測試用例添加到測試套件中

import unittestfrom test1.myunittest import Test3# from test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: # 輸出信息到控制臺 # 實例化一個TestSuite類 suite = unittest.TestSuite() # 把需要執(zhí)行的案例放在一個list中 tests = [Test3('test_add'), Test3('test_minus'), Test3('test_multi'), Test3('test_divide')] # 把案例添加到實例化好的測試套件中 suite.addTests(tests) # t = [t3('test_add'), t3('test_minus'), t3('test_multi'), t3('test_divide')] # suite.addTests(tests) # 實例化一個參數(shù)執(zhí)行類 runner = unittest.TextTestRunner(verbosity=2) # 測試執(zhí)行類的實例執(zhí)行測試套件 runner.run(suite)

以上的案例我們是添加一個文件的測試案例,我們同樣可以添加多個文件中的案例到一個測試套件中,然后執(zhí)行這個測試套件即可

import unittestfrom test1.myunittest import Test3from test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: # 輸出信息到控制臺 # 實例化一個TestSuite類 suite = unittest.TestSuite() # 把需要執(zhí)行的案例放在一個list中 tests = [Test3('test_add'), Test3('test_minus'), Test3('test_multi'), Test3('test_divide')] # 把案例添加到實例化好的測試套件中 suite.addTests(tests) # 添加另外一個文件中的測試案例到測試套件中 t = [t3('test_add'), t3('test_minus'), t3('test_multi'), t3('test_divide')] suite.addTests(t) # 實例化一個參數(shù)執(zhí)行類 runner = unittest.TextTestRunner(verbosity=2) # 測試執(zhí)行類的實例執(zhí)行測試套件 runner.run(suite)

上面的執(zhí)行方式是輸出結果到控制臺,我們也可以輸出結果到文件中

import unittestfrom test1.myunittest import Test3from test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: # 輸出信息到txt文件中 suite = unittest.TestSuite() tests = [Test3('test_add'), Test3('test_minus'), Test3('test_multi'), Test3('test_divide')] suite.addTests(tests) t = [t3('test_add'), t3('test_minus'), t3('test_multi'), t3('test_divide')] suite.addTests(t) with open(’UnittestTextReport.txt’, ’a’) as f: runner = unittest.TextTestRunner(stream=f, verbosity=2) runner.run(suite)

3、直接添加測試類到測試套件中

案例一個一個添加還是比較麻煩,我們可以直接添加一個測試類到測試套件中

利用下面的方法加載一個測試類

unittest.TestLoader().loadTestsFromTestCase(t3)

import unittestfrom unittest import TestLoaderfrom test1 import myunittestfrom test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: suite = unittest.TestSuite() loader = TestLoader() test_cases1 = unittest.TestLoader().loadTestsFromTestCase(t3) # 參數(shù)是一個類,而這個類必須是unittest.TestCase的子類或者孫類 suite.addTests(test_cases1) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)

4、直接加載一個模塊到測試套件中,如果這個模塊中有多個類,則會把所有的類的測試案例加載到測試套件中

unittest.TestLoader().loadTestsFromModule(myunittest)

import unittestfrom unittest import TestLoaderfrom test1 import myunittestfrom test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: suite = unittest.TestSuite() loader = TestLoader() test_cases1 = unittest.TestLoader().loadTestsFromModule(myunittest) # 參數(shù)是一個模塊,會把這個模塊里的所有case加載進來 suite.addTests(test_cases1) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)

我給大家截圖看下

python自動化測試三部曲之unittest框架的實現(xiàn)

5、通過案例名稱添加案例到測試套件中

test_cases1 = unittest.TestLoader().loadTestsFromName(’test1.myunittest2.Test3.test_minus’)

import unittestfrom unittest import TestLoaderfrom test1 import myunittestfrom test1.myunittest2 import Test3 as t3if __name__ == ’__main__’: suite = unittest.TestSuite() loader = TestLoader() test_cases1 = unittest.TestLoader().loadTestsFromName(’test1.myunittest2.Test3.test_minus’) # 加載某個cese runner = unittest.TextTestRunner(verbosity=2) suite.addTests(test_cases1) runner.run(suite)

我截圖給大家看下目錄結構

python自動化測試三部曲之unittest框架的實現(xiàn)

五、忽略執(zhí)行案例

在實際的項目中,有些案例我們可能暫時不需要執(zhí)行,如果有這樣的問題,我們該怎么辦,unittest框架已經(jīng)為我們提供了解決方案

1、無條件跳過該案例,用該裝飾器修飾要執(zhí)行的案例,則該案例會被忽略不執(zhí)行

@unittest.skip('do not exec')

@unittest.skip('do not exec') # 無條件跳過執(zhí)行該案例 def test_add(self): self.assertEqual(3,func.add(1,2))

2、滿足某個條件才跳過該案例

@unittest.skipIf(4 > 3,'2 > 3 do not exec')

@unittest.skipIf(4 > 3,'2 > 3 do not exec') # 滿足某個條件才跳過執(zhí)行 def test_minus(self): self.assertEqual(4,func.minus(5,1))

3、不滿足某個條件才跳過案例

@unittest.skipUnless(4 < 3,'hahah')

@unittest.skipUnless(4 < 3,'hahah') # 不滿足某個條件才跳過執(zhí)行 def test_multi(self): self.assertEqual(4,func.multi(2,2))

4、我們也可以在案例里面定義忽略執(zhí)行這條案例

def test_divide(self): self.skipTest('wydd') self.assertEqual(10,func.divide(100,10))

六、斷言

斷言就是判斷實際測試結果與預期結果是否一致,一致則測試通過,否則失敗。因此,在自動化測試中,無斷言的測試用例是無效的,這是因為當一個功能自動化已經(jīng)全部實現(xiàn),在每次版本迭代中執(zhí)行測試用例時,執(zhí)行的結果必須是權威的,也就是說自動化測試用例執(zhí)行結果應該無功能性或者邏輯性問題,在自動化測試中最忌諱的就是自動化測試的用例雖然是通過的,但是被測試的功能卻是存在問題的,自動化測試用例經(jīng)常應用在回歸測試中,發(fā)現(xiàn)的問題不是特別多,如果測試結果存在功能上的問題,則投入了人力去做的自動化參數(shù)就沒有多大的意義了,所以每一個測試用例必須要有斷言;在測試的結果中只有兩種可能,一種是執(zhí)行通過,另外一種是執(zhí)行失敗,也就是功能存在問題,在TestCase類中提供了assert方法來檢查和報告失敗,常用的方法如下

self.assertEqual(3,func.add(1,2)) # 判斷是否相等self.assertNotEqual() # 判斷是否不等于self.assertTrue() # 判斷布爾值是否為Trueself.assertFalse() # 判斷布爾值是否為Falseself.assertIs() # 判斷類型是否相同self.assertIsNot() # 判斷類型是否不同self.assertIsNone() # 判斷是否為Noneself.assertIsNotNone() # 判斷是否不為Noneself.assertIn() # 判斷在某個范圍內self.assertNotIn() # 判斷是否不在某個范圍內self.assertIsInstance() # 判斷是否為某個類的實例self.assertNotIsInstance()

到此這篇關于python自動化測試三部曲之unittest框架的實現(xiàn)的文章就介紹到這了,更多相關python unittest框架內容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 镀锌钢格栅_热镀锌格栅板_钢格栅板_热镀锌钢格板-安平县昊泽丝网制品有限公司 | 耐酸泵,耐腐蚀真空泵,耐酸真空泵-淄博华舜耐腐蚀真空泵有限公司 精密模具-双色注塑模具加工-深圳铭洋宇通 | 达利园物流科技集团- | 北京易通慧公司从事北京网站优化,北京网络推广、网站建设一站式服务商-北京网站优化公司 | 铝板冲孔网,不锈钢冲孔网,圆孔冲孔网板,鳄鱼嘴-鱼眼防滑板,盾构走道板-江拓数控冲孔网厂-河北江拓丝网有限公司 | 字典-新华字典-在线字典查字-字典趣| 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 吲哚菁绿衍生物-酶底物法大肠菌群检测试剂-北京和信同通科技发展有限公司 | 密封圈_泛塞封_格莱圈-[东莞市国昊密封圈科技有限公司]专注密封圈定制生产厂家 | 5L旋转蒸发器-20L-50L旋转蒸发器-上海越众仪器设备有限公司 | 德国GMN轴承,GMN角接触球轴承,GMN单向轴承,GMN油封,GMN非接触式密封 | 伸缩器_伸缩接头_传力接头-巩义市润达管道设备制造有限公司 | 洗地机-全自动/手推式洗地机-扫地车厂家_扬子清洁设备 | 利浦顿蒸汽发生器厂家-电蒸汽发生器/燃气蒸汽发生器_湖北利浦顿热能科技有限公司官网 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 服务器之家 - 专注于服务器技术及软件下载分享 | 杭州中央空调维修_冷却塔/新风机柜/热水器/锅炉除垢清洗_除垢剂_风机盘管_冷凝器清洗-杭州亿诺能源有限公司 | 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 广东青藤环境科技有限公司-水质检测 | 找果网 | 苹果手机找回方法,苹果iPhone手机丢了找回,认准找果网! | 爆破器材运输车|烟花爆竹运输车|1-9类危险品厢式运输车|湖北江南专用特种汽车有限公司 | 猎头招聘_深圳猎头公司_知名猎头公司 | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 广州冷却塔维修厂家_冷却塔修理_凉水塔风机电机填料抢修-广东康明节能空调有限公司 | 学校用栓剂模,玻璃瓶轧盖钳,小型安瓿熔封机,实验室安瓿熔封机-长沙中亚制药设备有限公司 | 排烟防火阀-消防排烟风机-正压送风口-厂家-价格-哪家好-德州鑫港旺通风设备有限公司 | 旋振筛|圆形摇摆筛|直线振动筛|滚筒筛|压榨机|河南天众机械设备有限公司 | NBA直播_NBA直播免费观看直播在线_NBA直播免费高清无插件在线观看-24直播网 | 湖南档案密集架,智能,物证,移动,价格-湖南档案密集架厂家 | 德国EA可编程直流电源_电子负载,中国台湾固纬直流电源_交流电源-苏州展文电子科技有限公司 | 青岛代理记账_青岛李沧代理记账公司_青岛崂山代理记账一个月多少钱_青岛德辉财税事务所官网 | 北京晚会活动策划|北京节目录制后期剪辑|北京演播厅出租租赁-北京龙视星光文化传媒有限公司 | 温州中研白癜风专科_温州治疗白癜风_温州治疗白癜风医院哪家好_温州哪里治疗白癜风 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 全自动过滤器_反冲洗过滤器_自清洗过滤器_量子除垢环_量子环除垢_量子除垢 - 安士睿(北京)过滤设备有限公司 | 山东钢格板|栅格板生产厂家供应商-日照森亿钢格板有限公司 | 破碎机锤头_合金耐磨锤头_郑州宇耐机械工程技术有限公司 | 电伴热系统施工_仪表电伴热保温箱厂家_沃安电伴热管缆工业技术(济南)有限公司 | 长沙印刷厂-包装印刷-画册印刷厂家-湖南省日大彩色印务有限公司 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 【法利莱住人集装箱厂家】—活动集装箱房,集装箱租赁_大品牌,更放心 |