先简要概述微信公众号如何进行第三方配置(Django)
配置
微信官方文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1472017492_58YV5接口测试公众号
申请:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
需要设置Url,token,域名等信息,token是自定义的服务器的验证码自定义菜单
通过服务器向网站https://api.weixin.qq.com/cgi-bin/menu/create?access_token=XXXX
进行POST操作来创建菜单,参数为类似如下格式的字符串:
menu = {
'button': [
{
"name": "服务",
"sub_button": [
{
"type": "click",
"name": "抢啥",
"key": event_keys['book_what'],
},
{
"type": "click",
"name": "查票",
"key": event_keys['get_ticket'],
},
{
"type": "click",
"name": "绑定",
"key": event_keys['account_bind'],
},
{
"type": "click",
"name": "帮助",
"key": event_keys['help'],
}
]
},
{
"name": "抢票",
"sub_button": []
}
]
}
- 用户事件响应:通过对微信发过来的POST事件进行解析、认证后,直接发送给对应的handler列表进行检查,让他们对这些数据进行对应的相应。
单元测试
如果已经进行好相关的配置,又已经实现相关的Handler处理,那就该进行单元测试了。
此时的单元测试最大的困难就是模拟按键以及输入信息,那如何做到呢?
修改配置
在单元测试中,首先设置settings.IGNORE_WECHAT_SIGNATURE = True
,防止微信的验证阻拦等
xml格式
实际上微信公众号规定了按键操作以及输入操作的信息格式,均为xml,在官方文档里有说明。此处仅仅介绍自定义菜单的操作以及发送文本消息的xml格式:
文本消息xml模板:xxxx是你的微信公众号的id,下面的{}内的为变量,可以在微信公众开发平台上查找:
fromUser是用户的id,curTime是当前时间,textMsg是文本消息的内容
<xml>
<ToUserName>< ![CDATA[xxxx] ]></ToUserName>
<FromUserName>< ![CDATA[{fromUser}] ]></FromUserName>
<CreateTime>{curTime}</CreateTime>
<MsgType>< ![CDATA[text] ]></MsgType>
<Content>< ![CDATA[{textMsg}] ]></Content>
<MsgId>{msgId}</MsgId>
</xml>
自定义菜单事件xml模板:xxxx是你的微信公众号的id,下面的{}内的为变量,可以在微信公众开发平台上查找:
fromUser是用户的id,curTime是当前时间,EVENTKEY是菜单中设置的键值,例如上述的event_keys['help']
<xml>
<ToUserName><![CDATA[xxxx]]></ToUserName>
<FromUserName><![CDATA[{fromUser}]]></FromUserName>
<CreateTime>{curTime}</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[CLICK]]></Event>
<EventKey><![CDATA[{EVENTKEY}]]></EventKey>
</xml>
既然有了模板,我们就可以模拟输入了,接下来需要解决的就是如何将输入post到后端:
注意需要post到/wechat/,同时制定xml格式,其中的self是TestCase子类下的
response = self.client.post(
path='/wechat/',
content_type='application/xml',
data=data
)
以下是一个完整模拟访问帮助功能的测试类:
class TestHelpOrSubscribe(TestCase):
def setUp(self):
# 设置配置
settings.IGNORE_WECHAT_SIGNATURE = True
# user1 => not bind
# user2 => bind
User.objects.create(open_id='abc')
User.objects.create(open_id='a', student_id='2016013265')
# textMsgs => 用户一般可能输入(成功)
self.textMsgs = ['帮助', 'Help', 'help', 'HELP']
# clickEvents => 用户一般可能点击事件
self.clickEvents = [CustomWeChatView.event_keys['help']]
# 是否返回帮助
def is_help(self, content):
pattern = '“紫荆之声”使用指南'
return content.find(pattern) != -1
def test_text(self):
users = User.objects.all()
for user in users:
for textMsg in self.textMsgs:
fromUser = user.open_id
curTime = str(getTimeStamp(datetime.datetime.now()))
msgId = str(random.randint(0, 99999)) + curTime
data = getTextXml(fromUser, curTime, textMsg, msgId)
response = self.client.post(
path='/wechat/',
content_type='application/xml',
data=data
)
content = str(response.content.decode('utf-8'))
self.assertEqual(self.is_help(content), True)
def test_event_click(self):
users = User.objects.all()
for user in users:
for clickEvent in self.clickEvents:
fromUser = user.open_id
curTime = str(getTimeStamp(datetime.datetime.now()))
data = getClickXml(fromUser, curTime, clickEvent)
response = self.client.post(
path='/wechat/',
content_type='application/xml',
data=data
)
content = str(response.content.decode('utf-8'))
self.assertEqual(self.is_help(content), True)
如果有对测试不了解的,请看我之前的Django单元测试文档:https://www.jianshu.com/p/5533c866453a
这样就完成了对微信公众号接口的测试。