python 如何在測試中使用 Mock
Mock概念
mock 的意思是模擬,也就是模擬接口返回的信息,用已有的信息替換它需要返回的信息,從實現對所依賴的模塊的測試。
一般有兩種場景:
- 前端對後端接口的 mock,
- 後端服務之間的測試中涉及的mock,常常發生在單元測試的時候。
前端mock可以通過一些工具來完成:
- 使用抓包工具Fiddler,Charles 來實現,通過修改代理返回的數據,實現多種場景的測試。
- 使用一些API管理工具來模擬,比如yapi,Easy Mock 等
- 當然有編碼能力的,也可以使用node.js,python的fastAPI來模擬
後端的 Mock 則是從接口的角度,如果一個接口A返回的數據需要依賴於另一個接口B,當敏捷開發中B接口還未開發完全時候這裡會需要用到 Mock。
對於測試人員,對接口測試的時候,部分接口尚未開發完成,在約定瞭接口定義之後,也可以使用 Mock 來模擬。
在 python3.X 中 Mock 模塊已經被集成到unittest裡面。
Mock類
class Mock(spec=None,side_effect=None,return_value=DEFAULT,name=None)
- spec:定義Mock對象的屬性值,可以是一個列表,字符串,一個對象的實例
- side_effect:可以用來拋出異常或者動態改變返回值,可以覆蓋return_value
- return_value:定義mock的返回值
- name:作為mock對象的標識可以在print時候看到
簡單的例子體驗下 Mock 的功能特點
from unittest import mock def add(num1,num2): return num1 + num2 # pass add = mock.Mock(return_value=200) # 創建mock對象 print( add(10,20) )
你會發現無論輸入的參數是什麼,輸出結果都是200。等於方法被 Mock 攔截處理瞭。
一個相對正式的 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 出現錯誤') 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(): ''' 待實現 return 200 ''' return 0 import unittest from unittest import mock class TestScmApi(unittest.TestCase): needmock = True def setUpClass(): print("setUpClass():所有方法之前執行") def tearDownClass(): print("tearDownClass():所有方法之後執行") def setUp(self): self.scmapi = scmapi() print("setUp():每個方法之前執行") def tearDown(self): print("teardown():每個方法之後執行") 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 出現錯誤') 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 出現錯誤') if __name__ == '__main__': unittest.main()
斷言方法
基本的斷言方法提供瞭測試結果是True還是False。所有的斷言方法都有一個msg參數,如果指定msg參數的值,則將該信息作為失敗的錯誤信息返回。
序號 | 斷言方法 | 斷言描述 |
---|---|---|
1 | assertEqual(arg1, arg2, msg=None) | 驗證arg1=arg2,不等則fail |
2 | assertNotEqual(arg1, arg2, msg=None) | 驗證arg1 != arg2, 相等則fail |
3 | assertTrue(expr, msg=None) | 驗證expr是true,如果為false,則fail |
4 | assertFalse(expr,msg=None) | 驗證expr是false,如果為true,則fail |
5 | assertIs(arg1, arg2, msg=None) | 驗證arg1、arg2是同一個對象,不是則fail |
6 | assertIsNot(arg1, arg2, msg=None) | 驗證arg1、arg2不是同一個對象,是則fail |
7 | assertIsNone(expr, msg=None) | 驗證expr是None,不是則fail |
8 | assertIsNotNone(expr, msg=None) | 驗證expr不是None,是則fail |
9 | assertIn(arg1, arg2, msg=None) | 驗證arg1是arg2的子串,不是則fail |
10 | assertNotIn(arg1, arg2, msg=None) | 驗證arg1不是arg2的子串,是則fail |
11 | assertIsInstance(obj, cls, msg=None) | 驗證obj是cls的實例,不是則fail |
12 | assertNotIsInstance(obj, cls, msg=None) | 驗證obj不是cls的實例,是則fail |
以上就是python 如何在測試中使用 Mock的詳細內容,更多關於python 測試中使用Mock的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- python unittest單元測試的步驟分析
- Python中的Unittest基本使用
- Python接口自動化淺析登錄接口測試實戰
- Python接口自動化系列之unittest結合ddt的使用教程詳解
- python中的unittest框架實例詳解