企业微信api文档:https://work.weixin.qq.com/api/doc/90000/90135/91039
pytest文档:https://www.osgeo.cn/pytest/contents.html
使用pytest框架,代码分层如下
初步的test_case.py文件
以3个接口作为示例:
- 获取token
- 获取客户群列表
- 获取客户群详情
1 接口要放在前置条件 setup_class
3 接口依赖于 2 接口获取的 chat_id
# case test_wechat.py
import requests
class TestWhatCompany:
token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
corpid = 'xxx'
corpsecret = 'xxx'
token = None
@classmethod
def setup_class(cls):
# 获取access_token,并放到前置条件
r = requests.get(
cls.token_url,
params={'corpid': cls.corpid, 'corpsecret': cls.corpsecret}
)
assert r.json()['errcode'] == 0
cls.token = r.json()['access_token']
def test_group_chat_list(self):
# 获取客户群列表
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list'
r = requests.post(url,
params={'access_token': self.token},
json={'offset': 0, 'limit': 15}
)
assert r.json()['errcode'] == 0
def test_group_chat_get(self):
# 获取客户群详情,依赖于客户群列表接口返回的chat_id
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get'
r = requests.post(url,
params={'access_token': self.token},
json={'offset': 0, 'limit': 15}
)
chat_id = r.json()['group_chat_list'][0]['chat_id'] # 拿到客户群详情接口的chat_id
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get'
r = requests.post(url,
parse=self.token,
json={'chat_id': chat_id} # 将上一个接口的chat_id 作为入参
)
assert r.json()['errcode'] == 0
优化后的test_case.py文件
获取客户群详情的case,需要用的另一个case的返回数据,我们就只能在这个case里再跑一遍上面的接口,这样代码会太雍肿。跟UI自动化一样,我们要把业务代码跟case分离,如下:
# 业务代码 group_chat.py
import requests
import json
class GroupChat:
@classmethod
def list(cls, token, offset, limit, **kwargs):
"""
获取客户群列表
:return: r.json()
"""
json = {'offset': offset, 'limit': limit} # 单独拿出json数据
json.update(kwargs) # 若有传入其他参数,一并加到json中
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list'
r = requests.post(url,
params={'access_token': token},
json=json
)
return r.json()
@classmethod
def get(cls, token, chat_id):
"""
获取客户群详情
:return: r.json()
"""
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get'
r = requests.post(url,
params=token,
json={'chat_id': chat_id}
)
print(json.dumps(r.json(), indent=2)) # 以json格式打印
return r.json()
入参决定测试数据,返回值决定断言数据
# case test_wechat.py
import requests
from test_api.group_chat import GroupChat
class TestWhatCompany:
token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
corpid = 'xxx'
corpsecret = 'xxx'
token = None
@classmethod
def setup_class(cls):
"""
前置方法,获取access_token
"""
r = requests.get(
cls.token_url,
params={'corpid': cls.corpid, 'corpsecret': cls.corpsecret}
)
assert r.json()['errcode'] == 0
cls.token = r.json()['access_token']
cls.group_chat = GroupChat()
def test_group_chat_get(self):
"""
获取客户群列表
"""
r = GroupChat.list(token=self.token, offset=0, limit=10)
assert r['errcode'] == 0
def test_group_what_get(self):
"""
获取客户群详情
"""
r = GroupChat.list(token=self.token, offset=0, limit=10)
chat_id = r['group_chat_id'][0]['chat_id']
r = GroupChat.get(token=self.token, chat_id=chat_id)
assert r['errcode'] == 0
封装token
# token封装 token.py
import requests
class Token:
token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
corpid = 'xxx'
token = dict() # 将token定义为一个字典
@classmethod
def get_token(cls, secret):
"""
token的封装,所有case从该方法调用token
"""
if secret not in cls.token.keys(): # 加上判断条件,避免重复请求,达到复用token的目的
r = cls.get_access_token(secret)
cls.token[secret] = r['access_token'] # 根据传入secret的不同,来调用不同的token
return cls.token[secret]
@classmethod
def get_access_token(cls, secret):
"""
token的业务代码,用来写token的用例
"""
r = requests.get(
cls.token_url,
params={'corpid': cls.corpid, 'corpsecret': secret}
)
return r.json()
token封装之后同步变动test_case.py
# test_case.py
from test_api.base import Token
from test_api.group_chat import GroupChat
class TestWhatCompany:
secret = 'xxx'
@classmethod
def setup_class(cls):
cls.group_chat = GroupChat()
cls.token = Base.get_token(cls.secret)
def test_get_token(self):
"""
获取token
"""
r = Base.get_access_token(secret=self.secret)
assert r['errcode'] == 0
def test_group_chat_list(self):
"""
获取客户群列表
:return:
"""
r = self.group_chat.list(token=self.token, offset=0, limit=10)
assert r['errcode'] == 0
def test_group_what_get(self):
"""
获取客户群详情
"""
r = self.group_chat.list(token=self.token, offset=0, limit=10)
chat_id = r['group_chat_list'][0]['chat_id']
r = self.group_chat.get(self.token, chat_id)
assert r['errcode'] == 0
业务分离
上面我们封装token之后,生成了两方方面的业务,一方面我们要对获取token接口进行测试,另一方面要对两个客户群接口进行测试,处理方法如下:
新建两个 Python Package,分别为api、testcase:
api中存放业务文件,分别为token.py、group_chat.py;
testcase中存放用例文件,分别为test_token.py、test_group_chat.py。
这样我们就实现的用例和业务的隔离、不同业务和不同用例之间的隔离,之后我们通过继承和链式调用来使代码更加简约、优雅。
具体代码实现如下:
# token.py
import requests
from test_api.api.base_api import BaseApi
class Token(BaseApi):
token_url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
corpid = 'xxx'
secret = 'xxx'
rc_secret = 'xxx'
token = dict() # 将token定义为一个字典
@classmethod
def get_token(cls, secret):
if secret not in cls.token.keys(): # 加上判断条件,避免重复请求,达到复用token的目的
r = cls.get_access_token(secret)
cls.token[secret] = r['access_token'] # 根据传入secret的不同,来调用不同的token
return cls.token[secret]
@classmethod
def get_access_token(cls, secret):
r = requests.get(
cls.token_url,
params={'corpid': cls.corpid, 'corpsecret': secret}
)
return r.json()
继承token.py的Token类,这样在需要token参数的时候可以直接 self.get_token(self.secret) 进行调用
# group_chat.py
import requests
from test_api.api.token import Token
class GroupChat(Token):
def list(self, offset, limit, **kwargs):
"""
获取客户群列表
:return:
"""
json = {'offset': offset, 'limit': limit}
json.update(kwargs)
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list'
r = requests.post(url,
params={'access_token': self.get_token(self.secret)},
json=json
)
# todo:自动加解密
# todo:多环境支持,根据配置可以一套case测试多套环境,需要修改host
self.format(r)
return r.json()
def get(self, chat_id):
"""
获取客户群详情
:return:
"""
url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get'
r = requests.post(url,
params={'access_token': self.get_token(self.secret)},
json={'chat_id': chat_id})
self.format(r)
return r.json()
# test_token.py
from test_api.api.token import Token
class TestToken:
def test_get_token(self):
"""
获取access_token
:return:
"""
r = Token.get_access_token(Token.secret) # 把secret放在Token类中,实现case中的数据分离
assert r['errcode'] == 0
# test_group_chat.py
from test_api.api.group_chat import GroupChat
class TestGroupChat:
@classmethod
def setup_class(cls):
cls.group_chat = GroupChat()
def test_group_chat_list(self):
"""
获取客户群列表
:return:
"""
r = self.group_chat.list(offset=0, limit=10)
assert r['errcode'] == 0
def test_group_what_get(self):
"""
获取客户群详情
"""
r = self.group_chat.list(offset=0, limit=10)
chat_id = r['group_chat_list'][0]['chat_id']
r = self.group_chat.get(chat_id)
assert r['errcode'] == 0