給大家安利一款超好用的測試框架-pytest

pytest 是什么娇斩?

pytest是python中非常流行的ut測試框架盖喷,這個框架有多流行呢夯秃? 應(yīng)該說現(xiàn)在比較新的開源項目基本都已經(jīng)使用pytest用來寫UT了愤惰,比如我們熟悉的requests,ansible锨推,flask铅歼, pypy等庫有興趣的同學(xué)不妨去Github上看下對應(yīng)的test目錄下的測試文件,全部都是用pytest作為UT測試框架的换可。而且Pycharm椎椰,VSCode等IDE已經(jīng)原生支持這個框架,只要在設(shè)置中將默認框架從unittest切換為pytest即可沾鳄。并且這個框架在用戶群體中也有非常高的評價慨飘,比如:

image.png

當(dāng)然這個框架除了作為ut測試框架以外,用來做BDD或者E2E測試也是完全沒有問題的译荞。比如接口測試框架HttpRunner3.0就是直接包了一層pytest外加一些拓展實現(xiàn)的瓤的。

為什么pytest如此流行

筆者自己的經(jīng)歷來說,在接觸pytest之前曾經(jīng)在cucumber吞歼,behave圈膏,robotframework之間徘徊不定。直到發(fā)現(xiàn)了pytest這個框架以后篙骡,感覺就是duang~ 用起來各種流暢稽坤。下面來簡單介紹框架提供的幾個核心特點:

  1. 用例寫作非常簡練,沒有模版代碼糯俗,非常pythonic慎皱。寫作一個簡單的用例跟普通的代碼相差無幾,例如:

    def test_simple_case():
        b = [2, 3, 4]
        assert 1 in b
    

    運行測試只需要在同級目錄下輸入:

    $ pytest
    
  2. Assert重寫叶骨,更加友好的錯誤信息,定位問題一目了然:

    pytest重載了默認的assert方法祈匙,你可以像書寫普通的條件語句一樣書寫你的assert方法忽刽。再也不用記住其他框架里諸如AssertEqual, AssertContains這些關(guān)鍵字了天揖。并且在遇到Assertion失敗的時候,提供的上下文也非常簡潔明了跪帝。比如l下面的assertion錯誤信息今膊,可以非常直觀的看到出錯的地方在 index100的地方:

    
        def test_eq_list():
            long_list = [0, 1, 2] * 100
            a = long_list + [3, 4, 5]
            b = long_list + [4, 4, 5]
    >       assert a == b
    E       assert [0, 1, 2, 0, 1, 2, ...] == [0, 1, 2, 0, 1, 2, ...]
    E         At index 300 diff: 3 != 4
    E         Use -v to get the full diff
    
    
  3. Mark(類似其他框架里面的標簽)功能:

    Mark用來標記測試用例,用來方便的為測試用例添加屬性信息伞剑,以方便插件根據(jù)這些熟悉信息作一些特殊處理斑唬。比如內(nèi)置的skip, skipif, xfail等mark,就分別用來表示跳過黎泣,條件式跳過恕刘,預(yù)期內(nèi)的失敗用例。比如下面的例子抒倚,可以標記某些case在windows的環(huán)境上跳過執(zhí)行等:

    import sys
    
    import pytest
    
    
    def test_normal_case():
        """no skip mark function"""
        pass
    
    
    @pytest.mark.skip(reason="not implemented yet")
    def test_in_the_future():
        raise NotImplemented
    
    
    # class-level mark
    @pytest.mark.skipif(sys.platform == 'win32',
                        reason="not  applicable on windows x86")
    class TestPosixCalls(object):
    
        def test_only_available_in_linux(self):
            """will not be setup or run under 'win32' platform"""
    
    

    而一些其他插件比如pytest-repeat褐着, pytest-timeout等,則分別使用@pytest.mark.repeat()@pytest.mark.timeout()來單獨標記某些需要重復(fù)執(zhí)行多次的用例以及用例執(zhí)行執(zhí)行超時控制(超時則停止執(zhí)行并且標記為失斖信弧)含蓉。

  4. Fixture(類似其他框架里的setup/teardown,依賴注入项郊,共享實例等)系統(tǒng):

    1. 使用yield聲明測試前與測試后執(zhí)行代碼馅扣,語法非常簡潔,例如:

      @pytest.fixture()
      def db_session(scope="session"):
          db = DBSession('scratch')
          db.connect()
          yield db
          db.close()
      
      
      def test_query_data(db_session):
            # do something with db_session here
          assert pass
       
      def test_update_data(db_session):
            # do something with db_session here
          assert pass
      

      這里將db_session聲明為一個fixture着降,并且作為參數(shù)傳入測試用例差油,用例就可以直接基于這個db_session做操作。無需關(guān)心具體的數(shù)據(jù)庫連接和斷開時機鹊碍。由于fixutre是支持function厌殉,class,module侈咕,session不同層級的共享公罕,這里我們將scope設(shè)置為session,意思是這一輪測試里面耀销,db.connect和db.close()方便按需進行實例化:

    2. 支持參數(shù)化用例聲明楼眷,例如:

      import pytest
      
      
      @pytest.mark.parametrize("test_input,expected", [
          ("3+5", 8),
          ("2+4", 6),
          pytest.param("6*9", 42,
                       marks=pytest.mark.xfail),
      ])
      def test_eval(test_input, expected):
          assert eval(test_input) == expected
      
      

      在實際執(zhí)行時會得到類似如下的輸出,也就是同樣的步驟在不同的輸入情況下的輸出用例:

      collected 3 items  
      fixture/test_parametrize.py::test_eval[3+5-8] PASSED                                                                                                              [ 33%]
      fixture/test_parametrize.py::test_eval[2+4-6] PASSED                                                                                                                 [ 66%]
      fixture/test_parametrize.py::test_eval[6*9-42] XFAIL                                                                                                                 [100%]
      
      
  1. 插件系統(tǒng)

    作為測試框架熊尉,pytest有著非常好的插件系統(tǒng)設(shè)計罐柳。框架本身基于pluggy框架開發(fā)狰住,通過調(diào)用定義良好的hooks來實現(xiàn)配置张吉,收集,執(zhí)行和報告這些過程催植。官方收錄的插件列表就有300+肮蛹,并且插件開發(fā)也比較容易上手勺择,只需要了解一下框架提供的幾個hook和一些類的屬性,有興趣的同學(xué)也可以看下筆者的個人博客的介紹伦忠。

注:有些內(nèi)容因為截圖比較多省核,大家可以結(jié)合附件的PPT一起看。這里就不再贅述了昆码。限于篇幅以及筆者水平气忠,還有一些高級的功能無法給到家娓娓道來,有興趣的同學(xué)可以直接去官網(wǎng)看教程赋咽。

總的來說旧噪,筆者的感慨就是好的框架想要走的長遠都需要在三個點上花功夫:

  • 簡單: 這個很大程度上決定你的受眾有多少,也就是你能走多快的問題冬耿;

  • 可靠:我們當(dāng)然不會選擇一個簡單易出錯或者一拓展就懵逼的這種框架舌菜,可靠的框架會在使用中不斷積累用戶口碑,吸引更多用戶加入亦镶。

  • 易拓展:這個基本上決定你能走多遠日月,沒有拓展性的框架一般壽命不會長久,很快就會被新的框架替代缤骨。pytest正是借助其良好的插件系統(tǒng)設(shè)計爱咬,拓展了許許多多非常實用的功能。畢竟绊起,沒人人比用戶更懂自己的需求(喬布斯除外)精拟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市虱歪,隨后出現(xiàn)的幾起案子蜂绎,更是在濱河造成了極大的恐慌,老刑警劉巖笋鄙,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件师枣,死亡現(xiàn)場離奇詭異,居然都是意外死亡萧落,警方通過查閱死者的電腦和手機践美,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來找岖,“玉大人陨倡,你說我怎么就攤上這事⌒聿迹” “怎么了兴革?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蜜唾。 經(jīng)常有香客問我杂曲,道長箕昭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任解阅,我火速辦了婚禮,結(jié)果婚禮上泌霍,老公的妹妹穿的比我還像新娘货抄。我一直安慰自己,他們只是感情好朱转,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布蟹地。 她就那樣靜靜地躺著,像睡著了一般藤为。 火紅的嫁衣襯著肌膚如雪怪与。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天缅疟,我揣著相機與錄音分别,去河邊找鬼。 笑死存淫,一個胖子當(dāng)著我的面吹牛耘斩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桅咆,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼括授,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岩饼?” 一聲冷哼從身側(cè)響起荚虚,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎籍茧,沒想到半個月后版述,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡硕糊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年院水,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片简十。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡檬某,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出螟蝙,到底是詐尸還是另有隱情恢恼,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布胰默,位于F島的核電站场斑,受9級特大地震影響漓踢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜漏隐,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一喧半、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧青责,春花似錦挺据、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至产阱,卻和暖如春婉称,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背构蹬。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工王暗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怎燥。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓瘫筐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铐姚。 傳聞我的和親對象是個殘疾皇子策肝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345