欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章搞懂Python Unittest測試方法的執(zhí)行順序

 更新時間:2021年09月17日 09:07:15   作者:軟件測試君  
unittest是Python標(biāo)準(zhǔn)庫自帶的單元測試框架,是Python版本的JUnit,下面這篇文章主要給大家介紹了如何通過一篇文章搞懂Python Unittest測試方法的執(zhí)行順序,需要的朋友可以參考下

Unittest

unittest大家應(yīng)該都不陌生。它作為一款博主在5-6年前最常用的單元測試框架,現(xiàn)在正被pytest,nose慢慢蠶食。

漸漸地,看到大家更多的討論的內(nèi)容從unittest+HTMLTestRunner變?yōu)閜ytest+allure2等后起之秀。

不禁感慨,終究是自己落伍了,跟不上時代的大潮了。

回到主題

感慨完了,回到正文。雖然unittest正在慢慢被放棄,但是它仍然是一款很全面的測試框架。

今天在群里看到有個群友的一番言論,激起了我的一番回憶。

自己以前是知道unittest的執(zhí)行順序并不是按照編寫test方法的順序執(zhí)行,而是按照字典序執(zhí)行的。但遺憾的是我都是投機(jī)取巧去解決的問題(后面會講)。

下面我們就來探討下unittest類的test方法的執(zhí)行順序問題。

源碼初窺

研究一下源碼(unittest.TestLoader)可以發(fā)現(xiàn),在加載一個class下面的test方法的時候,原生Loader進(jìn)行了排序,并且根據(jù)functools.cmp_to_key方法對測試方法列表進(jìn)行了排序。

我們知道,unittest是不需要我們指定對應(yīng)的方法,說白了,它是從類里面自動獲取到咱們的方法,并約定了以test開頭的方法都會被視為測試方法。

可以看到testMethodPrefix,即測試方法前綴,如果不是test開頭則直接return False

查詢一下self.sortTestMethodsUsing(這個是一個排序的方式)。

可以看到這個比較方法寫的很明確了,如果x < y那么返回-1,x = y則返回0,x > y返回1。

其實大家可能不知道Python里面的字符串也是可以比較的,在此必須說明一下字典序。我們來看看這個例子:

a = "abc"
b = "abcd"
c = "abce"
print(a > b)
print(b > c)

猜猜看執(zhí)行結(jié)果,很顯然,字典序的比較,是按A-Z的順序來比較的,如果前綴一樣但長度不一樣,那么長度長的那個,字典序靠后。

了解了字典序以后,我們就不難知道,在unittest里面它尋找case的過程可以這樣簡化:

  • 找到對應(yīng)類下面以test開頭的測試方法
  • 對他們進(jìn)行字典序排序
  • 依次執(zhí)行

這樣就不難解釋為什么我們有時候?qū)懙腸ase不按照自己想的順序來。

回到問題的本質(zhì)

搞清楚為什么用例會亂,那就想到對應(yīng)的解決方案。由于修改源碼是不太合適的,那我們有2個策略去達(dá)成目的。

比如我有多個test方法:

class Testcase(unittest.TestCase):

    def setUp(self) -> None:
        pass

    def test_1(self):
        print("執(zhí)行第一個")

    def test_2(self):
        print("第二個")

    def test_3(self):
        print("第三個")

    def test_10(self):
        print("第四個")

    def test_11(self):
        print("第五個")

    def tearDown(self) -> None:
        pass
        
if __name__ == "__main__":
    unittest.main()

執(zhí)行起來,按照字典序,其實是1 10 11 2 3的順序。

可以看到現(xiàn)在還是不對的

1. 以字典序的方式編寫test方法

我們可以手動修改test方法的名稱,這也是我早前的處理方式。也就是說把想要先執(zhí)行的case字典序排到前面:

class Testcase(unittest.TestCase):

    def setUp(self) -> None:
        pass

    def test_0_1(self):
        print("執(zhí)行第一個")

    def test_0_2(self):
        print("第二個")

    def test_0_3(self):
        print("第三個")

    def test_1_0(self):
        print("第四個")

    def test_1_1(self):
        print("第五個")

    def tearDown(self) -> None:
        pass

我們可以把數(shù)字按位數(shù)拆開,個位數(shù)就把10位補(bǔ)0,這樣就能達(dá)到效果,如果會寫100個case,我們就需要補(bǔ)2個0,比如0_0_1,當(dāng)然一個文件里面也不會有太多case。

如果遇到test_login這種怎么辦呢,不是數(shù)字結(jié)尾的方法。

其實是一樣的,可以寫成test_數(shù)字_業(yè)務(wù)的模式。番貨寫了一個裝飾器專門解決這樣的問題,大家可以去參考下。

2. 回歸本質(zhì),從根本解決問題

方案1用了番貨的裝飾器,好是好,但是改變了方法本身的名稱,我們其實可以針對他的排序方式入手,按照我們編寫case的順序排序測試方法,就能達(dá)到想要的目的。

說說思路:

  • 手寫一個loader繼承自TestLoader類,改寫里面的排序方法
  • 在unittest運(yùn)行的時候傳入這個新的loader

來看看完整代碼,注釋里面寫的很完善了。

import unittest


class MyTestLoader(unittest.TestLoader):
    def getTestCaseNames(self, testcase_class):
        # 調(diào)用父類的獲取“測試方法”函數(shù)
        test_names = super().getTestCaseNames(testcase_class)
        # 拿到測試方法list
        testcase_methods = list(testcase_class.__dict__.keys())
        # 根據(jù)list的索引對testcase_methods進(jìn)行排序
        test_names.sort(key=testcase_methods.index)
        # 返回測試方法名稱
        return test_names


class Testcase(unittest.TestCase):

    def setUp(self) -> None:
        pass

    def test_1(self):
        print("執(zhí)行第一個")

    def test_2(self):
        print("第二個")

    def test_3(self):
        print("第三個")

    def test_10(self):
        print("第四個")

    def test_11(self):
        print("第五個")

    def tearDown(self) -> None:
        pass


if __name__ == "__main__":
    unittest.main(testLoader=MyTestLoader())

執(zhí)行了一下還是不對,是不是哪里出了什么問題呢?

是因為pycharm有一種默認(rèn)的unittest的調(diào)試方法,我們要改成普通的方法去執(zhí)行。

試試用控制臺執(zhí)行:

也沒什么毛病

總結(jié)

到此這篇關(guān)于如何通過一篇文章搞懂Python Unittest測試方法的執(zhí)行順序的文章就介紹到這了,更多相關(guān)Python Unittest測試執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Tornado協(xié)程在python2.7如何返回值(實現(xiàn)方法)

    Tornado協(xié)程在python2.7如何返回值(實現(xiàn)方法)

    下面小編就為大家?guī)硪黄猅ornado協(xié)程在python2.7如何返回值(實現(xiàn)方法)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 舉例詳解Python中循環(huán)語句的嵌套使用

    舉例詳解Python中循環(huán)語句的嵌套使用

    這篇文章主要介紹了舉例詳解Python中循環(huán)語句的嵌套使用,是Python入門中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-05-05
  • Python?Tkinter庫從入門到進(jìn)階使用教程

    Python?Tkinter庫從入門到進(jìn)階使用教程

    Tkinter是Python標(biāo)準(zhǔn)庫中內(nèi)置的圖形用戶界面(GUI)工具包,提供了創(chuàng)建窗口、按鈕、文本框等GUI元素的功能,本文將介紹Tkinter的基礎(chǔ)知識,幫助大家快速入門
    2023-12-12
  • django框架兩個使用模板實例

    django框架兩個使用模板實例

    這篇文章主要介紹了django框架使用模板方法,結(jié)合兩個具體實例形式詳細(xì)分析了Django框架模板的相關(guān)使用技巧與操作注意事項,需要的朋友可以參考下
    2019-12-12
  • Python爬蟲獲取全網(wǎng)招聘數(shù)據(jù)實現(xiàn)可視化分析示例詳解

    Python爬蟲獲取全網(wǎng)招聘數(shù)據(jù)實現(xiàn)可視化分析示例詳解

    這篇文章主要介紹了Python爬蟲獲取全網(wǎng)招聘數(shù)據(jù)實現(xiàn)可視化分析示例詳解,實現(xiàn)采集一下最新的qcwu招聘數(shù)據(jù),本文列舉了部分代碼以及實現(xiàn)思路,需要的朋友可以參考下
    2023-07-07
  • 教你用Pygame制作簡單的貪吃蛇游戲

    教你用Pygame制作簡單的貪吃蛇游戲

    貪吃蛇(也叫做貪食蛇)游戲是一款休閑益智類游戲,既簡單又耐玩,唯一的目標(biāo)就是做這條gai上最長(pang)的蛇(zhu),這篇文章主要給大家介紹了關(guān)于如何使用Pygame制作簡單的貪吃蛇游戲的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 攻擊者是如何將PHP Phar包偽裝成圖像以繞過文件類型檢測的(推薦)

    攻擊者是如何將PHP Phar包偽裝成圖像以繞過文件類型檢測的(推薦)

    這篇文章主要介紹了攻擊者是如何將PHP Phar包偽裝成圖像以繞過文件類型檢測的,需要的朋友可以參考下
    2018-10-10
  • Python實現(xiàn)讀取及寫入csv文件的方法示例

    Python實現(xiàn)讀取及寫入csv文件的方法示例

    這篇文章主要介紹了Python實現(xiàn)讀取及寫入csv文件的方法,涉及Python針對csv格式文件的讀取、遍歷、寫入等相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • 深入了解如何基于Python讀寫Kafka

    深入了解如何基于Python讀寫Kafka

    這篇文章主要介紹了深入了解如何基于Python讀寫Kafka,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • 用Python爬取各大高校并可視化幫弟弟選大學(xué),弟弟直呼牛X

    用Python爬取各大高校并可視化幫弟弟選大學(xué),弟弟直呼牛X

    高考結(jié)束了,接下來最重要的就是玩玩玩,然后準(zhǔn)備報志愿吧.中國教育在線網(wǎng)顯示國內(nèi)目前共有2857所高等院校,報一個理想的學(xué)校簡直是千里挑一.正好表弟求著我讓我?guī)退x學(xué)校,我想著十年寒窗苦讀也不容易不如就用python幫幫他.分析一下目前國內(nèi)的大學(xué),需要的朋友可以參考下
    2021-06-06

最新評論