測試Python代碼


作為程序員,懂得測試,這是必須的職業技能。很遺憾,我以前從未意識到這點,因此經歷了很多叫苦不迭的開發生涯。當然了,期望每個人都成為測試高手也是不可能的,但是最基本的單元測試啥的是不惜的,尤其是現在中小公司測試開發不分家的情況下,懂得測試簡直是優秀程序員的標志啊。這篇博客就介紹一下Python的測試方法,主要是單元測試。

mock

在介紹具體的測試方法之前,先介紹一下mock,簡單來說,mock的作用就是要達到一種掛羊頭賣狗肉的效果。例如,你想測試一個web客戶端,如果為了測試去搭建一個真實的web服務器,這個代價就太大了。這時候,我們就可以創建一個mock對象,通過一些接口模擬一個web服務器,從而簡化了測試的難度,而且這樣一個mock對象,可控性很好,模擬延時、斷線等都非常簡單,而如果是真實的服務器程序就要麻煩的多了。

Tim Mackinnon總結了一些需要使用mock對象的情況:

1、真實對象具有不可確定的行為(產生不可預測的結果,如股票的行情)

2、真實對象很難被創建(比如具體的web容器)

3、真實對象的某些行為很難觸發(比如網絡錯誤)

4、真實情況令程序的運行速度很慢

5、真實對象有用戶界面

6、測試需要詢問真實對象它是如何被調用的(比如測試可能需要驗證某個回調函數是否被調用了)

7、真實對象實際上並不存在(當需要和其他開發小組,或者新的硬件系統打交道的時候,這是一個普遍的問題)

Python中的mock模塊就是這個作用,使用pip install mock就可以安裝,在3.3之后,這個模塊歸入了后邊要講的unittest模塊,也成了標准庫的一部分了。

下面的內容基本都是mock文檔中的東西,簡單翻譯一下放在這里。

Mock和 MagicMock是mock模塊中核心的兩個類,當你訪問這些類的實例對象的某個屬性時,這些對象會為你創建這些屬性(如果不存在)並且會記錄下你使用這些屬性的方式。你可以指定這些對象被調用時的返回值或者可用的屬性,然后使用斷言對結果進行驗證。你也可以使用side_effect來拋出異常或者是mock對象被調用時返回不同的值。

>>> from mock import MagicMock
>>> thing = ProductionClass()
# 設定返回值為3 >>> thing.method = MagicMock(return_value=3) >>> thing.method(3, 4, 5, key='value') # 注意調用參數
# 可以使用斷言判斷返回值是否為3 3 >>> thing.method.assert_called_with(3, 4, 5, key='value') #驗證調用參數是否正確 >>> mock = Mock(side_effect=KeyError('foo')) >>> mock() Traceback (most recent call last): ... KeyError: 'foo' >>> values = {'a': 1, 'b': 2, 'c': 3} >>> def side_effect(arg): ... return values[arg] ... >>> mock.side_effect = side_effect >>> mock('a'), mock('b'), mock('c') (1, 2, 3) >>> mock.side_effect = [5, 4, 3, 2, 1] >>> mock(), mock(), mock() (5, 4, 3)

  使用patch裝飾器可以很容易的模擬一個類或者其對象。

>>> from mock import patch
>>> @patch('module.ClassName2')
... @patch('module.ClassName1')
... def test(MockClass1, MockClass2):
...     module.ClassName1()
...     module.ClassName2()

...     assert MockClass1 is module.ClassName1
...     assert MockClass2 is module.ClassName2
...     assert MockClass1.called
...     assert MockClass2.called
...
>>> test()

  

doctest

doctest是Python中非常基本的一個測試方式,從名字可以看得出來,它是基於文檔的測試,那么是這個文檔有什么格式要求呢?簡單的說就是測試用例都要寫的和python交互方式下的輸入輸出一致,而其他格式的文字這可以當作是注釋。假設文件shape.txt的內容如下

我們想要測試一個模塊shape,其中有一個類Point和Circle。類Point代表一個二維空間中的點,而Circle這代表一個圓形,其擁有一個方法area返回計算其面積

>>> import shape
>>> circle = shape.Circle(x=5, y=5, radius=5)
>>> circle.x
5
>>> circle.y
5
>>> circle.radius
5
>>> circle.area()
78.53981633974483

  運行python -m doctest shape.txt 即可進行doctest。簡單來說,doctest就像是個Python的命令行一樣,把<<<之后的內容執行,然后與緊隨在之后的輸出進行對比。如執行circle.x,判斷是不是為5,執行circle.area(),看起結果是否等於78.53981633974483

 

unittest

doctest雖然簡單易用,但是當測試用例需要很多准備工作時,就顯得力不從心,這是就該unittest大顯身手的時候了。關於unittest,這篇文章就不說了,說多了沒用,實干出真知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM