Mock接口请求
https://minitest.weixin.qq.com/#/minium/Python/api/App?id=mock_request
官网提供了一个mock_request
方法
在mock之后需要使用restore_request
方法清除掉所有mock request的匹配规则
查看官方例子
#!/usr/bin/env python3
import minium
class RequestTest(minium.MiniTest):
def test_mock_request(self):
self.app.restore_request() # 清空规则
mock_resp1 = {"data": "mock result1", "statusCode": 200}
mock_resp2 = {"data": "mock result2", "statusCode": 200}
mock_resp3 = {"data": "mock result3", "statusCode": 200}
rule1 = ".*/SendMsg\\?.*"
url1 = "http://minitest.weixin.qq.com/SendMsg?content=test"
rule2 = {"url": ".*/SendMsg$"}
url2 = "http://minitest.weixin.qq.com/SendMsg"
rule3 = {"url": ".*/SendMsg.*", "data": {"content": "^\\d+$"}}
url3 = "http://minitest.weixin.qq.com/SendMsgData"
data = {"content": "12557"}
# 加入规则1
self.app.mock_request(rule1, success=mock_resp1)
result = self.app.call_wx_method("request", [{"url": url1}]).get("result", {}).get("result")
self.assertDictEqual(result, mock_resp1) # 返回mock1的数据
with self.assertRaises(minium.MiniAppError):
self.app.call_wx_method("request", [{"url": url2}]) # 规则不匹配,调用原request方法
# 加入规则2
self.app.mock_request(rule2, success=mock_resp2)
result = self.app.call_wx_method("request", [{"url": url2}]).get("result", {}).get("result")
self.assertDictEqual(result, mock_resp2) # 返回mock2的数据
# 加入规则3
self.app.mock_request(rule3, success=mock_resp3)
result = self.app.call_wx_method("request", [{"url": url2, "data": data}]).get("result", {}).get("result")
self.assertDictEqual(result, mock_resp2) # 虽然与规则3也匹配,但优先匹配规则2,返回mock2的数据
result = self.app.call_wx_method("request", [{"url": url3, "data": data}]).get("result", {}).get("result")
self.assertDictEqual(result, mock_resp3) # 返回mock3的数据
可以看到例子中都是重复的内容,拿出其中一个最小的例子阅读
mock_resp1 = {"data": "mock result1", "statusCode": 200}
rule1 = ".*/SendMsg\\?.*"
url1 = "http://minitest.weixin.qq.com/SendMsg?content=test"
# 配置一个mock规则rule1,成功返回mock_resp1
self.app.mock_request(rule1, success=mock_resp1)
# 发起一个http请求
result = self.app.call_wx_method("request", [{"url": url1}]).get("result", {}).get("result")
# 查看响应(result)是否与预期(mock_resp1)一致
self.assertDictEqual(result, mock_resp1)
封装自己的mock_request方法
将它们使用python会话的方式处理
class MockRequest:
def __init__(self, app, **kwargs):
self.app = app
self.kwargs = kwargs
def __enter__(self):
self.app.mock_request(**self.kwargs)
def __exit__(self, exc_type, exc_val, exc_tb):
self.app.restore_request()
这样使用with
关键字就可以进行mock和mock规则清理了
将它封装成我们自己的mock_request方法
@allure.step("mock 接口请求")
def mock_request(self, rule: str or dict, success=None, fail=None):
"""
:param rule: 规则
:param success: 成功返回的数据
:param fail: 失败返回的数据
with mock_request(rule={"url": ".*/SendMsg.*"}, success={"data": "mock result3", "statusCode": 200}):
...
"""
return MockRequest(self.app, rule=rule, success=success, fail=fail)
传入匹配规则+成功响应/失败响应
Mock函数
mock掉小程序API的调用
同理,封装一个可以使用with
关键字调用的类
class MockWxMethod:
"""
https://minitest.weixin.qq.com/#/minium/Python/api/App?id=mock_wx_method
"""
def __init__(self, app, **kwargs):
self.app = app
self.kwargs = kwargs
self.method = self.kwargs.get("method")
def __enter__(self):
logger.info(f"开启{self.method}的mock")
self.app.mock_wx_method(**self.kwargs)
def __exit__(self, exc_type, exc_val, exc_tb):
logger.info(f"关闭{self.method}的mock")
self.app.restore_wx_method(self.method)
在enter的时候开启mock,在exit的时候关闭mock
处理对话框
在使用下方代码点击确认的时候发现没有反应
customer_page.native.handle_modal(btn_text="确认")
阅读一下这个弹框使用的代码
使用的是 wx.showModal(Object object)
https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showModal.html
直接mock掉这个响应,让它返回成功,所以代码修改为
customer_page.app.mock_wx_method("showModal", result={"confirm": True})
customer_page.click(customer_page.delete_button)
customer_page.app.restore_wx_method("showModal")
将它封装一下
@allure.step("处理对话框")
def confirm_dialog(self, flag=True, method="showModal", result=None):
"""
:param flag: True=确认,False=取消
:param method:
:param result: 传入result时,flag不起作用
:return:
"""
if result is None:
return MockWxMethod(self.app, method=method, result={"confirm": flag})
else:
return MockWxMethod(self.app, method=method, result=result)
使用时候就是
with customer_page.confirm_dialog(True):
customer_page.click(customer_page.delete_button)
处理呼叫请求
在操作模拟拨号的时候也遇到了相同的问题
点击拨打按钮弹出一个呼叫对话框
开发对应的代码为
Taro.makePhoneCall({
phoneNumber: phone,
}).catch(() => {});
从官方文档找到对应的API
wx.makePhoneCall(Object object)
https://developers.weixin.qq.com/miniprogram/dev/api/device/phone/wx.makePhoneCall.html
对该API进行Mock,因为我们需要测试一下拨打的号码是否正确,所以将它打印出来
def mock_make_phone_call(self, result=None):
if result is None:
result = {"confirm": False}
return MockWxMethod(self.app, method="makePhoneCall",
functionDeclaration="""function(options){console.log(options)}""", result=result)
通过捕获日志的方式拿到拨打的电话号码
customer_page.g_log_message_list[-1].args[0].get('phoneNumber')
全部代码
with customer_page.mock_make_phone_call():
customer_page.click(customer_page.one_customer_phone(name))
try:
phone_number = customer_page.g_log_message_list[-1].args[0].get('phoneNumber')
except Exception as e:
phone_number = None
if phone != "":
assert phone_number == phone, f'点击添加了「{phone}」手机号的「{name}」用户的拨打按钮后号码为「{phone_number}」'
else:
assert phone_number is None, f'点击没有添加手机号的「{name}」用户的拨打按钮出现呼叫弹框(呼叫被mock,截图不展示)'