Python3的單元測試模塊Mock與性能測試模塊CProfile

原文轉載自「劉悅的技術博客」https://v3u.cn/a_id_92

我們知道寫完了代碼需要自己跑一跑進行測試,一個寫好的程序如果連測試都沒有就上到生產環境是不敢想象的,這麼做的人不是太自信就是太無知。

傳統測試無非就是自己運行一下程序查看結果,或者前後端服務進行聯調,這裏要說的是走正規流程的單元測試,那到底什麼是單元測試呢?顧名思義,只測試當前單元的程序或者代碼,也可以理解當前模塊的代碼塊,單元測試假設所有的內部或外部的依賴應該是穩定的, 已經在別處進行測試過的.使用mock 就可以對外部依賴組件實現進行模擬並且替換掉, 從而使得單元測試將焦點只放在當前的單元功能。

簡單地說,mock就是幫我們解決測試依賴的一個模塊,在Python3中,mock已經被集成到了unittest單元測試框架中,所以不需要單獨安裝,可以直接使用。

什麼情況下使用mock
在項目的單元測試過程中,會遇到:
1、接口的依賴
2、外部接口調用
3、測試環境非常複雜

代碼示例:

def add_and_multiply(x, y):
    addition = x + y
    multiple = multiply(x, y)
    return (addition, multiple)

def multiply(x, y):
    return x * y

class MyTestCase(unittest.TestCase):

    def test_add_and_multiply(self):
        x = 3
        y = 5
        addition, multiple = add_and_multiply(x, y)
        self.assertEqual(8, addition)
        self.assertEqual(15, multiple)

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

如上,我們要測試A模塊,然後A模塊依賴於B模塊的調用。但是,由於B模塊的改變,導致了A模塊返回結果的改變,從而使A模塊的測試用例失敗。其實,對於A模塊,以及A模塊的用例來說,並沒有變化,不應該失敗纔對。

這個時候就是mock發揮作用的時候了。通過mock模擬掉影響A模塊的部分(B模塊)。至於mock掉的部分(B模塊)應該由其它用例來測試。

總有人吐槽 Python 的性能低下,但是 Python 本質其實也不是用來做計算任務的,Python 是一門膠水語言,是用來寫業務邏輯的,而不是用來寫CPU密集的算法的。事實上覆雜的解析一般都會用 C++ 這種硬核語言來寫了,比如 numpy TensorFlow lxml。大多數程序員一天 90% 的工作除了和PM撕逼以外,也就是在寫 CRUD,也就是調用這些包。所以瓶頸一般在 IO 上而不在 CPU 上,而解決 IO 的瓶頸手段就多了,Python 中至少有 多進程、多線程、AsyncIO、Gevent 等多種方法。不過方法多其實也是一個弊端,這幾種方法可以說是基本互不兼容,對各種第三方庫的支持也參差不齊。

而測試python程序的cpu瓶頸,就需要cProfile模塊了,cProfile是一種確定性分析器,只測量CPU時間,並不關心內存消耗和其他與內存相關聯的信息。

cprofile在python3.7.2裏是內置模塊,不需要單獨安裝。

cProfile 有多種調用方法,可以直接從命令行調用:

python -m cProfile -s tottime 你的腳本.py

其中的 -s 的意思是 sort。常用的 sort 類型有兩個:

tottime,指的是函數本身的運行時間,扣除了子函數的運行時間
cumtime,指的是函數的累計運行時間,包含了子函數的運行時間

要獲得對程序性能的全面理解,經常需要兩個指標都看一下。

至此,使用cprofile就可以很簡單的看出你寫的程序是否性能堪憂了,不過性能這個問題其實是典型的木桶理論的場景,系統的整體性能是由最差的一塊決定的。所以也是一個不斷迭代的過程。

原文轉載自「劉悅的技術博客」 https://v3u.cn/a_id_92

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章