前置准备
-
需要在飞书群聊中,添加一个机器人,获取webhook地址。
-
自定义需要发送的卡片样式 https://open.feishu.cn/cardkit
例如:我搭建了一个如下样式
后端代码实现
python
def feishu_send_message(result, id, info,
url=feishu_url):
object_list_1 = result['results']
# print(object_list_1)
headers = {"Content-Type": "application/json"}
payload_message = {
"msg_type": "interactive",
"card": {
"config": {
"wide_screen_mode": True
},
"i18n_elements": {
"zh_cn": [
# {
# "tag": "markdown",
# "content": "**数据总览** ",
# "text_align": "left",
# "text_size": "heading"
# },
{
"tag": "markdown",
"content": f":OnIt:**任务名**: {info['task']}",
"text_align": "left",
"text_size": "heading"
},
{
"tag": "markdown",
"content": f":VRHeadset:**执行环境**: {info['env']}",
"text_align": "left",
"text_size": "heading"
},
{
"tag": "column_set",
"flex_mode": "bisect",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "center",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "default",
"elements": [
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": ":DONE:总用例数",
"text_align": "center",
"text_size": "normal"
},
{
"tag": "column_set",
"flex_mode": "none",
"horizontal_spacing": "default",
"background_style": "default",
"columns": [
{
"tag": "column",
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": f"{result['all']}",
"text_size": "heading",
"text_align": "center",
"text_color": "default"
}
}
],
"width": "weighted",
"weight": 1
}
]
},
{
"tag": "markdown",
"content": "<text_tag color='blue'>总共100%</text_tag>",
"text_align": "center",
"text_size": "normal"
}
],
"weight": 1
}
],
"margin": "0px 0px 0px 0px"
}
],
"weight": 1
},
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "default",
"elements": [
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": ":PRAISE:成功用例数",
"text_align": "center",
"text_size": "normal"
},
{
"tag": "column_set",
"flex_mode": "none",
"horizontal_spacing": "default",
"background_style": "default",
"columns": [
{
"tag": "column",
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": f"{result['success']}",
"text_size": "heading",
"text_align": "center",
"text_color": "green"
}
}
],
"width": "weighted",
"weight": 1
}
]
},
{
"tag": "markdown",
"content": f"<text_tag color='green'>成功率{format(result['success'] / result['all'] * 100, '.2f')}%</text_tag>",
"text_align": "center",
"text_size": "normal"
}
],
"weight": 1
}
],
"margin": "0px 0px 0px 0px"
}
],
"weight": 1
},
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "default",
"elements": [
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "8px",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": ":SHOCKED:失败用例数",
"text_align": "center",
"text_size": "normal"
},
{
"tag": "column_set",
"flex_mode": "none",
"horizontal_spacing": "default",
"background_style": "default",
"columns": [
{
"tag": "column",
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": f"{result['fail'] + result['error']}",
"text_size": "heading",
"text_align": "center",
"text_color": "red"
}
}
],
"width": "weighted",
"weight": 1
}
]
},
{
"tag": "markdown",
"content": f"<text_tag color='red'>失败率{format((result['fail'] + result['error']) / result['all'] * 100, '.2f')}%</text_tag>",
"text_align": "center",
"text_size": "normal"
}
],
"weight": 1
}
],
"margin": "0px 0px 0px 0px"
}
],
"weight": 1
}
],
"margin": "16px 0px 0px 0px"
},
{
"tag": "hr"
},
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "center",
"vertical_spacing": "8px",
"background_style": "default",
"elements": [
{
"tag": "markdown",
"content": "**本次运行测试场景**",
"text_align": "left",
"text_size": "normal"
}
],
"weight": 1
}
],
"margin": "16px 0px 0px 0px"
},
]
},
"i18n_header": {
"zh_cn": {
"title": {
"tag": "plain_text",
"content": "接口测试任务报告"
},
"subtitle": {
"tag": "plain_text",
"content": f"时间:{str(datetime.datetime.now().strftime('%Y-%m-%d'))}"
},
"template": "blue",
"ud_icon": {
"tag": "standard_icon",
"token": "approval_colorful"
}
}
}},
}
for data in object_list_1:
payload_message['card']['i18n_elements']['zh_cn'].append(
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "center",
"vertical_spacing": "8px",
"background_style": "default",
"elements": [{
"tag": "markdown",
"content": f"{data['name']}",
"text_align": "center",
"text_size": "normal"
},
{
"tag": "column_set",
"flex_mode": "none",
"background_style": "default",
"horizontal_spacing": "8px",
"horizontal_align": "left",
"columns": [
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"vertical_spacing": "4px",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": f"该场景总用例数\n{data['all']}",
"text_align": "center",
"text_size": "notation"
}
],
"weight": 1,
"padding": "0px 0px 12px 0px"
},
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": f"该流程下执行成功用例数\n{data['success']}",
"text_align": "center",
"text_size": "notation"
}
],
"weight": 1
},
{
"tag": "column",
"width": "weighted",
"vertical_align": "top",
"background_style": "grey",
"elements": [
{
"tag": "markdown",
"content": f"执行失败用例数\n{data['fail'] + data['error']}",
"text_align": "center",
"text_size": "notation"
}
],
"weight": 1
}
],
"margin": "16px 0px 0px 0px"
}],
"weight": 1,
"padding": "0px 0px 0px 0px"
}
],
"margin": "16px 0px 4px 0px"
}
)
payload_message['card']['i18n_elements']['zh_cn'].append(
{
"tag": "hr"
}
)
payload_message['card']['i18n_elements']['zh_cn'].append(
{
"elements": [
{
"content": f"[详细用例执行情况请网页查看](http://172.xx.xx.xx:8080/#/records/report/{id})",
"tag": "lark_md"
}
],
"tag": "note"
}
)
res = requests.post(url=url, headers=headers, data=json.dumps(payload_message), )
print(res.json())
return res.json()
后端代码,前端只需要传入record_id
python
@router.post('/send_report', summary='发送报告到飞书')
async def send_report(item: SendReportForm):
# print(item)
record_id = int(item.record_id)
result = await TestReport.get_or_none(record_id=record_id)
record = await TestRecord.get_or_none(id=record_id).prefetch_related('task', 'env')
info = {
"id": record.pk,
"task": record.task.name,
"env": record.env.name,
"tester": record.tester,
"all": record.all,
"success": record.success,
"fail": record.fail,
"error": record.error,
"pass_rate": record.pass_rate,
"run_time": record.run_time,
"status": record.status,
"create_time": record.create_time
}
feishu_send_message(result.info, record_id, info, feishu_url)
前端代码实现
前端只需要增加一个按钮,再配合点击事件
html
<el-button type="primary" @click="sendReport">发送测试报告到飞书</el-button>
//js
async function sendReport() {
const response = await http.task.sendReportApi(route.params.id)
if (response.status === 200){
ElMessage(
{
message: '发送成功',
type: 'success',
duration: 3000
}
)
}
}

飞书app得到的结果

点击最顶部的详情链接,可以打开网页查看获取详情。