python文件1-unittest單元測試之mock
什麼是mock
unittest.mock是一個用於在Python中進行單元測試的庫,Mock翻譯過來就是模擬的意思,顧名思義這個庫的主要功能是模擬一些東西。
它的主要功能是使用mock物件替代掉指定的Python物件,以達到模擬物件的行為。
學過python自動化的對unittest並不陌生,unittest其實是單元測試框架,
但對於單元測試,估計很多小夥伴都不懂,單元測試才是自動化測試的至高境界,其中mock是單元測試的脊髓所在
mock能做什麼:
-
1.前後端聯調,如果你是一個前端頁面開發,現在需要開發一個功能:
下一個訂單,支付頁面的介面,根據支付結果,支付成功,展示支付成功頁,支付失敗,展示支付失敗頁。
要完成此功能,你需要呼叫後端的介面,根據返回給你的結果,來展示不同的頁面。此時後端介面還沒開發好,
作為一個前端開發總不能等別人開發好了,你再開發,那你只有加班的命了。
為了同步開發完成任務,此時,你可以根據介面文件的規定,把介面的地址和入參傳過去,然後自己mock介面的不同返回介面,來完成前端的開發任務 -
2.單元測試,單元測試的目的是測試某個小小單元的功能,但現實中開發的函式或方法都是有依賴關係的,比如b函式的引數,需要呼叫a函式的返回結果,但是我前面已經測試a函數了
這種情況下,就不需要再測一次a函數了,此時就可以用mock模組來模擬呼叫這部分內容,並給出返回結果 -
3.第三方介面依賴,在做介面自動化的時候,有時候需要呼叫第三方的介面,但是別人公司的介面服務不受你的控制,有可能別人提供的測試環境今天服務給你開著,別人就關掉了,
給自動化介面測試帶來很多的麻煩,此時就可以自己寫一個mock-server來模擬介面的返回資料
mock環境準備
1.python2.x的版本,mock是一個獨立的模組,需要用pip安裝
pip install -U mock
3.從Python 3.3以後的版本mock已經合併到unittest模組中了,是unittest單元測試的一部分,直接匯入過來就行
from unittest import mock
依賴關係
1.如下場景:支付是一個獨立的介面,由其它開發提供,根據支付的介面返回狀態去顯示失敗,還是成功,這個是你需要實現的功能
也就是說你寫一個b功能,你的同事寫一個a功能,你的b功能需要根據a功能的結果去判斷,然後實現對應的功能。這就是存在依賴關係,你同事開發的進度你是無法控制的
你要是等他開發完了,你再開發,那你就坐等加班吧.
2.以下是自己寫的 zhifu_statues()函式功能,大概設計如下,儲存為temple.py檔案
# 儲存為temple.py
# coding:utf-8
def zhifu():
'''假設這裡是一個支付的功能,未開發完
支付成功返回:{"result": "success", "reason":"null"}
支付失敗返回:{"result": "fail", "reason":"餘額不足"}
reason返回失敗原因
'''
pass
def zhifu_statues():
'''根據支付的結果success or fail,判斷跳轉到對應頁面'''
result = zhifu()
print(result)
try:
if result["result"] == "success":
return "支付成功"
elif result["result"] == "fail":
print("失敗原因:%s" % result["reason"])
return "支付失敗"
else:
return "未知錯誤異常"
except:
return "Error, 服務端返回異常!"
3.單元測試用例設計
# coding:utf-8
from unittest import mock
import unittest
import temple
class Test_zhifu_statues(unittest.TestCase):
'''單元測試用例'''
def test_01(self):
'''測試支付成功場景'''
# mock一個支付成功的資料
temple.zhifu = mock.Mock(return_value={"result": "success", "reason":"null"})
# 根據支付結果測試頁面跳轉
statues = temple.zhifu_statues()
print(statues)
self.assertEqual(statues, "支付成功")
def test_02(self):
'''測試支付失敗場景'''
# mock一個支付成功的資料
temple.zhifu = mock.Mock(return_value={"result": "fail", "reason": "餘額不足"})
# 根據支付結果測試頁面跳轉
statues = temple.zhifu_statues()
self.assertEqual(statues, "支付失敗")
if __name__ == "__main__":
unittest.main()
4.單元測試是為了保證函式的每個分支都測到,以上zhifu_statues()函式有四個分支,也就是說要寫四個案例,這裡我只寫了2個