mock安装
pip install pytest-mock
mock使用
pytest中使用无需导入,只需要导入pytest就可使用,它提供了一个名为mocker
的fixture。使用方法:
def test(mocker): mocker.patch() ****
mock作用
1、解决接口依赖:当我们要测试一个接口,而这个接口所依赖的接口还没开发或者没开发完。这时候可以使用mock模拟所依赖的接口完成测试 。
2、单元测试:当我们所要测试的接口还未开发完,而我们还要完成测试用例代码的编写,我们可以先模拟这个接口进行测试。
3、调用第三方接口:当我们的接口需要调用第三方,而第三方接口我们还未得到权限或未购买时,可使用mock模拟进行测试。
4、前后端联调:当前端需要的接口后端还在开发,就可以使用mock模拟后端返回我们需要的数据。
mock实例
比如现在有这样一个场景,我们测试三网认证,而认证需要调用第三方聚合的接口,第三方认证接口还未购买。就可以使用mock先模拟测试。
接口:
''' Code description:实名认证 Create time:2020-10-30 Developer:叶修 ''' import requests class Api_Person_Auth(object): #第三方认证接口 def api_person_auth(self,real_name,id_card,mobile): url = 'http://v.juhe.cn/telecom/query'#第三方认证接口 body = { "real_name":real_name, "id_card":id_card, "mobile":mobile } r = requests.post(url, json=body)#请求第三方认证接口 #print(r.text) return r #返回信息 #我们的认证接口 def api_my_auth(self,real_name,id_card,mobile): #调用第三方认证接口 response = self.api_person_auth(real_name,id_card,mobile) try: if response['resultcode'] == '100': return '认证成功' elif response['resultcode'] == '101': return '认证失败' elif response['resultcode'] == "102": return '有必填参数为空' else: return '未定义错误' except Exception: return '系统异常' if __name__ == '__main__': Api_Person_Auth().api_person_auth()
接口是聚合三网认证接口,没有key的情况下,是不会调用成功的。
测试用例:
''' Code description: 实名认证 Create time: 2020/10/30 Developer: 叶修 ''' import sys import allure import pytest from common.logger import Log from common.read_yaml import ReadYaml from api.api_person_auth.api_person_auth import Api_Person_Auth testdata = ReadYaml("person_auth.yml").get_yaml_data()#读取参数化的数据 @allure.feature('实名认证') class Test_person_Auth(object): log = Log() @allure.title('实名认证') #使用parametrize参数化请求参数、状态码和返回信息 @pytest.mark.parametrize('real_name,id_card,mobile,expect', testdata['person_auth'], ids=['正确传入参数', '全部参数为空', '姓名为空', '姓名错误']) def test_person_auth(self, mocker,real_name, id_card, mobile, expect): self.log.info('%s,%s' % ((sys._getframe().f_code.co_name, '------认证接口-----'))) shili = Api_Person_Auth() # 实例化 #方法一 shili.api_person_auth = mocker.patch.object(Api_Person_Auth,'api_person_auth', return_value={'resultcode': expect['resultcode']})#引用参数化状态码 #当传入side_effect时,return_value就会失效,当调用真实的认证方法时,就会使用真实的认证方法,从而达到真实的测试如下: # shili.api_person_auth = mocker.patch.object(Api_Person_Auth, 'api_person_auth', # return_value={'resultcode': code},side_effect=shili.api_person_auth) #方法二 # mocker.patch第一个参数传模拟对象的具体路径api.api_person_auth.api_person_auth.Api_Person_Auth.api_person_auth # shili.api_person_auth = mocker.patch('api.api_person_auth.api_person_auth.Api_Person_Auth.' # 'api_person_auth', 'api_person_auth',return_value={'resultcode': '100'}) #加入side_effect参数,代码稍作修改,要调用真实认证方法 #msg = shili.api_person_auth(real_name,id_card,mobile) #不加入side_effect参数,调用自写的认证方法 msg = shili.api_my_auth(real_name,id_card,mobile) #加入side_effect参数,真实情况下返回msg.json() #self.log.info('%s:%s' % ((sys._getframe().f_code.co_name, '获取请求结果:%s' % msg.json()))) #不加入side_effect参数,模拟情况下直接返回msg self.log.info('%s:%s' % ((sys._getframe().f_code.co_name, '获取请求结果:%s' % msg))) # 模拟情况下断言 assert msg == expect['resultmsg']#断言响应信息
测试数据:
person_auth: - ['测试','371523199805170016','17854319777',{'resultcode':'100','resultmsg':'认证成功'}] - ['','','',{'resultcode':'102','resultmsg':'有必填参数为空'}] - ['','371523199805170016','17854319777',{'resultcode':'102','resultmsg':'有必填参数为空'}] - ['测试呀','371523199805170016','17854319777',{'resultcode':'101','resultmsg':'认证失败'}]
测试结果:
2020-10-30 16:02:10,930 - root - INFO - test_person_auth,------认证接口----- 2020-10-30 16:02:10,931 - root - INFO - test_person_auth:获取请求结果:认证成功 2020-10-30 16:02:10,933 - root - INFO - test_person_auth,------认证接口----- 2020-10-30 16:02:10,933 - root - INFO - test_person_auth:获取请求结果:有必填参数为空 PASSEDPASSEDPASSED2020-10-30 16:02:10,935 - root - INFO - test_person_auth,------认证接口----- 2020-10-30 16:02:10,936 - root - INFO - test_person_auth:获取请求结果:有必填参数为空 2020-10-30 16:02:10,938 - root - INFO - test_person_auth,------认证接口----- 2020-10-30 16:02:10,939 - root - INFO - test_person_auth:获取请求结果:认证失败 PASSED
总结
mock的基本使用在用例中已经介绍了,这里就不多解释了。工作中具体的使用需要大家实际中磨练。