02-Python Unittest 自動化單元測試框架Demo

1. unittest框架概述

  • unittest單元測試框架不僅可以適用于單元測試锁蠕,還可以適用WEB自動化測試用例的開發(fā)與執(zhí)行,
  • 該測試框架可組織執(zhí)行測試用例,并且提供了豐富的斷言方法,判斷測試用例是否通過掉丽,最終生成測試結(jié)果跌榔。
  • unittest是一個(gè)單元測試框架,是Python編程的單元測試框架机打。有時(shí)候,也做叫做“PyUnit”,是Junit的Python語言版本片迅。這里了解下,Junit是Java語言的單元測試框架残邀,Java還有一個(gè)很好用的單元測試框架叫TestNG,本系列只學(xué)習(xí)Python,所以只需要unittest是Python里的一個(gè)單元測試框架就可以了柑蛇。
  • 當(dāng)我們寫的用例越來越多時(shí)芥挣,我們就需要考慮用例編寫的規(guī)范與組織,以便于后期的維護(hù)耻台,而unittest正是這樣一款工具空免。

2. unittest框架原理

unittest支持測試自動化,共享測試用例中的初始化和關(guān)閉退出代碼盆耽,在unittest中最小單元是test蹋砚,也就是一個(gè)測試用例。要了解unittest單元測試框架摄杂,先來了解以下幾個(gè)重要的概念坝咐。

  • 測試固件(test fixture)
    一個(gè)測試固件包括兩部分,執(zhí)行測試代碼之前的準(zhǔn)備部分和測試結(jié)束之后的清掃代碼析恢。這兩部分一般用函數(shù)setUp()和tearDown()表示墨坚。這里舉例以下,例如要測試百度搜索selenium這個(gè)場景映挂,我們的測試固件可以這樣寫泽篮,setUp()里寫打開瀏覽器,瀏覽器最大化柑船,和打開百度首頁等腳本代碼帽撑;在tearDown()里寫結(jié)束搜索后,退出并關(guān)閉瀏覽器的代碼鞍时。
  • 測試用例(test case)
    unittest中管理的最小單元是測試用例油狂,一個(gè)測試用例,包括測試固件寸癌,和具體測試業(yè)務(wù)的函數(shù)或者方法专筷。一個(gè)測試用例中,測試固件可以不寫蒸苇,但是至少有一個(gè)已test開頭的函數(shù)磷蛹。unittest會自動化識別test開頭的函數(shù)是測試代碼,如果你寫的函數(shù)不是test開頭溪烤,unittest是不會執(zhí)行這個(gè)函數(shù)里面的腳本的味咳,這個(gè)千萬要記住庇勃,所有的測試函數(shù)都要test開頭,記住是小寫的哦槽驶。
  • 測試套件 (test suite)
    很簡單责嚷,就是很多測試用例的集合,叫測試套件掂铐,一個(gè)測試套件可以隨意管理多個(gè)測試用例罕拂。如果測試用例比作單個(gè)學(xué)生,測試套件就是好像是班級的概念全陨。
  • 測試執(zhí)行器 (test runner)
    test runner是一個(gè)用來執(zhí)行加載測試用例爆班,并執(zhí)行用例,且提供測試輸出的一個(gè)組建辱姨。test runner可以加載test case或者test suite進(jìn)行執(zhí)行測試任務(wù)柿菩。

案例

  • python 測試框架(本文只涉及 PyUnit)
    https://wiki.python.org/moin/PythonTestingToolsTaxonomy

  • 環(huán)境準(zhǔn)備
    首先確定已經(jīng)安裝有Python,之后通過安裝PyUnit雨涛,Python版本比較新的已經(jīng)集成有PyUnit(PyUnit 提供了一個(gè)圖形測試界面UnittestGUI.py)
    參考: https://wiki.python.org/moin/PyUnit

  • 代碼實(shí)例
    使用的IDE為 PyCharm,DEMO結(jié)構(gòu)如圖


    image.png
  • 1.簡單地一個(gè)實(shí)例

# Test002_Fail.py


# -*- coding:utf-8 -*-

import  unittest

class Test002_Fail(unittest.TestCase):

    #測試用例前執(zhí)行
    def setUp(self):
        print 'Case Before'
        pass

    #測試用例后執(zhí)行
    def tearDown(self):
        print 'Case After'
        pass

    #測試用例1
    def test_Case1(self):
        a = 3
        b = 2
        self.assertEqual(a+b,4,'Result Fail')

    #測試用例2
    def test_Case2(self):
        a = 2
        b = 3
        self.assertEqual(a*b,7,'Result Fail')

if __name__ == '__main__':
    unittest.main()

2.當(dāng)case比較多的時(shí)候枢舶,可以使用Suite來管理多個(gè)case,suite 可以看做是一個(gè)case 的容器,可以裝很多的case

# SuiteDemo.py


# -*- coding:utf-8 -*-


#一個(gè)類替久,添加測試集


import  unittest

class SuiteDemo(unittest.TestCase):


    #測試用例前執(zhí)行
    def setUp(self):
        print 'Case Before'
        pass

    #測試用例后執(zhí)行
    def tearDown(self):
        print 'Case After'
        pass


    def test_Case1(self):
        a = 3
        b = 2
        self.assertEqual(a+b,5,'Result Fail')
        print 'Case1'


    def test_Case2(self):
        a = 2
        b = 3
        self.assertEqual(a*b,6,'Result Fail')
        print 'Case2'



#定義一個(gè)測試集合祟辟,方便添加Case

def suite():
    suiteTest = unittest.TestSuite()
    suiteTest.addTest(SuiteDemo("test_Case1"))
    suiteTest.addTest(SuiteDemo("test_Case2"))
    return suiteTest



#默認(rèn)運(yùn)行時(shí)通過 Suite 運(yùn)行

if __name__ == '__main__':
    unittest.main(defaultTest='suite')

3.Suite 和 Case可以分開寫在不同的Python文件中,這樣方便區(qū)分case模塊和Suite管理模塊侣肄,在測試測試的時(shí)候只需要在case模塊里面添加case,之后添加到Suite模塊即可了
case模塊:

# TestCaseDemo


# -*- coding:utf-8 -*-


import unittest


class TestCaseDemo(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_Case1(self):
        print 'test_Case1'


    def test_Case2(self):
        print 'test_Case2'


    def test_Case3(self):
        print 'test_Case3'


    def test_Case4(self):
        print 'test_Case4'

接下來為三個(gè)Suite模塊旧困,都是先導(dǎo)入Case模塊,之后添加Suite,再在Suite里面添加Case稼锅,最后執(zhí)行的時(shí)候需要使用TestRunner,這個(gè)TestRunner 相當(dāng)于Suite 的執(zhí)行器
簡單地TestSuite:

# TestCase_Demo1.py


# -*- coding:utf-8 -*-


#集合寫入一個(gè)方法吼具,main調(diào)用并啟動



import unittest
from TestCase_Demo import TestCaseDemo


#添加一個(gè)測試集合,并添加Case

def suite():
    suiteTest = unittest.TestSuite()
    suiteTest.addTest(TestCaseDemo('test_Case1'))
    return suiteTest



#指定并啟動測試集合,運(yùn)行集合方法

if __name__ == '__main__':

    runner = unittest.TextTestRunner()
    runner.run(suite())

也可以不定義Suite方法矩距,直接在main方法中進(jìn)行Case的添加拗盒,之后執(zhí)行

# TestCase_Demo2.py


# -*- coding:utf-8 -*-


#集合可以寫在main


import unittest
from TestCase_Demo import TestCaseDemo


#指定并啟動測試集合

if __name__ == '__main__':

    #添加測試集合Case,并啟動
    suiteTest = unittest.TestSuite()
    suiteTest.addTest(TestCaseDemo('test_Case1'))
    suiteTest.addTest(TestCaseDemo('test_Case2'))

    #直接啟動集合
    runner = unittest.TextTestRunner()
    runner.run(suiteTest)

可以把不同的Case 添加道不同的Suite里面,同樣锥债,可以給Suite分組陡蝇,用于區(qū)分不同的Case,并且,Suite 之間還可以包含

# TestCase_Demo3.py


# -*- coding:utf-8 -*-


#包含集合哮肚,多集合



import unittest
from TestCase_Demo import TestCaseDemo



#添加不同的合集

def Suite1():
    suiteTest = unittest.TestSuite()
    suiteTest.addTest(TestCaseDemo("test_Case1"))
    suiteTest.addTest(TestCaseDemo("test_Case2"))
    print 'Suite1 運(yùn)行'
    return suiteTest


def Suite2():
    suiteTest = unittest.TestSuite()
    suiteTest.addTest(TestCaseDemo("test_Case3"))
    suiteTest.addTest(TestCaseDemo("test_Case4"))
    print 'Suite2 運(yùn)行'
    return suiteTest



#包含所有的Suite

def AllSuite():
    allTest = unittest.TestSuite((Suite1(),Suite2()))
    return allTest



#運(yùn)行的時(shí)候登夫,可以根據(jù)不同的要求,運(yùn)行不同的Suite,或者全部運(yùn)行允趟,這樣就方便管理每次運(yùn)行的case

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(AllSuite())

小結(jié)

PyUnit 是Python的一個(gè)單元測試框架恼策,使用它可以方便的管理自動化運(yùn)行的case.
在Python 中,每一個(gè)方法 只要方法名使用test_ 開頭的都被作為是一個(gè)用例潮剪,都可以看做成一個(gè)case,這里介紹了使用Suite管理Case涣楷,并且分組運(yùn)行Case,還有其他很多的功能分唾,請參考:
https://docs.python.org/2.7/library/unittest.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狮斗,隨后出現(xiàn)的幾起案子绽乔,更是在濱河造成了極大的恐慌,老刑警劉巖碳褒,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件折砸,死亡現(xiàn)場離奇詭異,居然都是意外死亡骤视,警方通過查閱死者的電腦和手機(jī)鞍爱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鹃觉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來专酗,“玉大人,你說我怎么就攤上這事盗扇〉豢希” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵疗隶,是天一觀的道長佑笋。 經(jīng)常有香客問我,道長斑鼻,這世上最難降的妖魔是什么蒋纬? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮坚弱,結(jié)果婚禮上蜀备,老公的妹妹穿的比我還像新娘。我一直安慰自己荒叶,他們只是感情好碾阁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著些楣,像睡著了一般脂凶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上愁茁,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天蚕钦,我揣著相機(jī)與錄音,去河邊找鬼鹅很。 笑死冠桃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的道宅。 我是一名探鬼主播食听,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胸蛛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了樱报?” 一聲冷哼從身側(cè)響起葬项,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎迹蛤,沒想到半個(gè)月后民珍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盗飒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年嚷量,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逆趣。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝶溶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宣渗,到底是詐尸還是另有隱情抖所,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布痕囱,位于F島的核電站田轧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鞍恢。R本人自食惡果不足惜傻粘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帮掉。 院中可真熱鬧弦悉,春花似錦、人聲如沸旭寿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盅称。三九已至肩祥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缩膝,已是汗流浹背混狠。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疾层,地道東北人将饺。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親予弧。 傳聞我的和親對象是個(gè)殘疾皇子刮吧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容