python 如何在測試中使用 Mock
Mock概念
mock 的意思是模擬,也就是模擬接口返回的信息,用已有的信息替換它需要返回的信息,從實(shí)現(xiàn)對(duì)所依賴的模塊的測試。
一般有兩種場景:
- 前端對(duì)后端接口的 mock,
- 后端服務(wù)之間的測試中涉及的mock,常常發(fā)生在單元測試的時(shí)候。
前端mock可以通過一些工具來完成:
- 使用抓包工具Fiddler,Charles 來實(shí)現(xiàn),通過修改代理返回的數(shù)據(jù),實(shí)現(xiàn)多種場景的測試。
- 使用一些API管理工具來模擬,比如yapi,Easy Mock 等
- 當(dāng)然有編碼能力的,也可以使用node.js,python的fastAPI來模擬
后端的 Mock 則是從接口的角度,如果一個(gè)接口A返回的數(shù)據(jù)需要依賴于另一個(gè)接口B,當(dāng)敏捷開發(fā)中B接口還未開發(fā)完全時(shí)候這里會(huì)需要用到 Mock。
對(duì)于測試人員,對(duì)接口測試的時(shí)候,部分接口尚未開發(fā)完成,在約定了接口定義之后,也可以使用 Mock 來模擬。
在 python3.X 中 Mock 模塊已經(jīng)被集成到unittest里面。
Mock類
class Mock(spec=None,side_effect=None,return_value=DEFAULT,name=None)
- spec:定義Mock對(duì)象的屬性值,可以是一個(gè)列表,字符串,一個(gè)對(duì)象的實(shí)例
- side_effect:可以用來拋出異?;蛘邉?dòng)態(tài)改變返回值,可以覆蓋return_value
- return_value:定義mock的返回值
- name:作為mock對(duì)象的標(biāo)識(shí)可以在print時(shí)候看到
簡單的例子體驗(yàn)下 Mock 的功能特點(diǎn)
from unittest import mock def add(num1,num2): return num1 + num2 # pass add = mock.Mock(return_value=200) # 創(chuàng)建mock對(duì)象 print( add(10,20) )
你會(huì)發(fā)現(xiàn)無論輸入的參數(shù)是什么,輸出結(jié)果都是200。等于方法被 Mock 攔截處理了。
一個(gè)相對(duì)正式的 Mock 例子
正常情況:
import requests def request_scm(): # res = requests.get('http://www.mysx-scm.com') res = requests.get('http://baidu.com') return res.status_code import unittest from unittest import mock class TestScmApi(unittest.TestCase): def testUrl(self): # request_scm = mock.Mock(return_value=200) self.assertEqual(request_scm(), 200, msg='testUrl 出現(xiàn)錯(cuò)誤') if __name__ == '__main__': unittest.main()
可以分別把兩個(gè) # 注釋移到下一句試試。
一個(gè)完整的測試?yán)?/h2>
import requests
class scmapi():
def request_scm():
res = requests.get('http://www.mysx-scm.com')
# res = requests.get('http://baidu.com')
return res.status_code
def pay_alipay():
'''
待實(shí)現(xiàn)
return 200
'''
return 0
import unittest
from unittest import mock
class TestScmApi(unittest.TestCase):
needmock = True
def setUpClass():
print("setUpClass():所有方法之前執(zhí)行")
def tearDownClass():
print("tearDownClass():所有方法之后執(zhí)行")
def setUp(self):
self.scmapi = scmapi()
print("setUp():每個(gè)方法之前執(zhí)行")
def tearDown(self):
print("teardown():每個(gè)方法之后執(zhí)行")
def test_request_scm(self):
if self.needmock:
scmapi.request_scm = mock.Mock(return_value=200)
self.assertEqual(scmapi.request_scm(), 200, msg='test_request_scm 出現(xiàn)錯(cuò)誤')
def test_pay_alipay(self):
if self.needmock:
scmapi.pay_alipay = mock.Mock(return_value=200)
self.assertEqual(scmapi.pay_alipay(), 200, msg='test_pay_alipay 出現(xiàn)錯(cuò)誤')
if __name__ == '__main__':
unittest.main()
import requests class scmapi(): def request_scm(): res = requests.get('http://www.mysx-scm.com') # res = requests.get('http://baidu.com') return res.status_code def pay_alipay(): ''' 待實(shí)現(xiàn) return 200 ''' return 0 import unittest from unittest import mock class TestScmApi(unittest.TestCase): needmock = True def setUpClass(): print("setUpClass():所有方法之前執(zhí)行") def tearDownClass(): print("tearDownClass():所有方法之后執(zhí)行") def setUp(self): self.scmapi = scmapi() print("setUp():每個(gè)方法之前執(zhí)行") def tearDown(self): print("teardown():每個(gè)方法之后執(zhí)行") def test_request_scm(self): if self.needmock: scmapi.request_scm = mock.Mock(return_value=200) self.assertEqual(scmapi.request_scm(), 200, msg='test_request_scm 出現(xiàn)錯(cuò)誤') def test_pay_alipay(self): if self.needmock: scmapi.pay_alipay = mock.Mock(return_value=200) self.assertEqual(scmapi.pay_alipay(), 200, msg='test_pay_alipay 出現(xiàn)錯(cuò)誤') if __name__ == '__main__': unittest.main()
斷言方法
基本的斷言方法提供了測試結(jié)果是True還是False。所有的斷言方法都有一個(gè)msg參數(shù),如果指定msg參數(shù)的值,則將該信息作為失敗的錯(cuò)誤信息返回。
序號(hào) | 斷言方法 | 斷言描述 |
---|---|---|
1 | assertEqual(arg1, arg2, msg=None) | 驗(yàn)證arg1=arg2,不等則fail |
2 | assertNotEqual(arg1, arg2, msg=None) | 驗(yàn)證arg1 != arg2, 相等則fail |
3 | assertTrue(expr, msg=None) | 驗(yàn)證expr是true,如果為false,則fail |
4 | assertFalse(expr,msg=None) | 驗(yàn)證expr是false,如果為true,則fail |
5 | assertIs(arg1, arg2, msg=None) | 驗(yàn)證arg1、arg2是同一個(gè)對(duì)象,不是則fail |
6 | assertIsNot(arg1, arg2, msg=None) | 驗(yàn)證arg1、arg2不是同一個(gè)對(duì)象,是則fail |
7 | assertIsNone(expr, msg=None) | 驗(yàn)證expr是None,不是則fail |
8 | assertIsNotNone(expr, msg=None) | 驗(yàn)證expr不是None,是則fail |
9 | assertIn(arg1, arg2, msg=None) | 驗(yàn)證arg1是arg2的子串,不是則fail |
10 | assertNotIn(arg1, arg2, msg=None) | 驗(yàn)證arg1不是arg2的子串,是則fail |
11 | assertIsInstance(obj, cls, msg=None) | 驗(yàn)證obj是cls的實(shí)例,不是則fail |
12 | assertNotIsInstance(obj, cls, msg=None) | 驗(yàn)證obj不是cls的實(shí)例,是則fail |
以上就是python 如何在測試中使用 Mock的詳細(xì)內(nèi)容,更多關(guān)于python 測試中使用Mock的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
對(duì)Pytorch 中的contiguous理解說明
這篇文章主要介紹了對(duì)Pytorch 中的contiguous理解說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03TensorFlow2.1.0安裝過程中setuptools、wrapt等相關(guān)錯(cuò)誤指南
這篇文章主要介紹了TensorFlow2.1.0安裝時(shí)setuptools、wrapt等相關(guān)錯(cuò)誤指南,本文通過安裝錯(cuò)誤分析給出大家解決方案,感興趣的朋友跟隨小編一起看看吧2020-04-04python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽基本操作,需要的朋友可以參考下2020-02-02python PyQt5中QRadioButton的詳細(xì)使用教程與應(yīng)用實(shí)戰(zhàn)
PyQt5是一個(gè)跨平臺(tái)的GUI工具包,用于創(chuàng)建具有Python綁定的Qt應(yīng)用程序,在PyQt5中,QRadioButton是一個(gè)非常有用的控件,用于在用戶界面上提供單選選項(xiàng),本文將詳細(xì)介紹QRadioButton的基本用法、常用屬性和方法,需要的朋友可以參考下2024-08-08python連接遠(yuǎn)程ftp服務(wù)器并列出目錄下文件的方法
這篇文章主要介紹了python連接遠(yuǎn)程ftp服務(wù)器并列出目錄下文件的方法,實(shí)例分析了Python使用pysftp模塊的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04解決Python3 被PHP程序調(diào)用執(zhí)行返回亂碼的問題
今天小編就為大家分享一篇解決Python3 被PHP程序調(diào)用執(zhí)行返回亂碼的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02python for 循環(huán)獲取index索引的方法
今天小編就為大家分享一篇python for 循環(huán)獲取index索引的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02