日报小工具 - 钉钉定时发送Wiki日报

前言:

测试日报是用来记录每天测试工作的完成情况、发现的问题,以及问题修复进度,以便团队了解项目进展、及时调整计划,并保持信息同步交流。每日发送测试日报属于重复性工作,开发日报小工具结合Jenkins进行定时自动发送,有效节约人力成本,提高了整体测试效能。

整体流程图:

1、获取Wiki有效内容:

python 复制代码
import configparser
import math
import requests
from loguru import logger
from bs4 import BeautifulSoup
import pandas as pd
import re

def confluence_read(content_id):
    config = configparser.ConfigParser()
    config.read('Conf/common.conf')
    # 构建API请求的headers
    headers = {
        'Content-Type': 'application/json'
    }
    url = f'https://xxxx.com/rest/api/content/{content_id}?expand=space,body.view,version,container'
    # 发送GET请求获取content
    response = requests.get(url, headers=headers, auth=('xxx', 'xxx'))
    # 检查响应状态码
    if response.status_code == 200:
        return response.json()
    else:
        logger.info(f'请求失败,code= {response.status_code}')

html_data = confluence_read(xxxxxx)

涉及获取Wiki文档json数据知识:
https://developer.atlassian.com/server/confluence/confluence-rest-api-examples/
https://docs.atlassian.com/atlassian-confluence/REST/6.6.0/#content-createContent

configparser使用:https://docs.python.org/zh-cn/3/library/configparser.html

2、处理json数据并解析文档

python 复制代码
def beaut_table_data(html_data):
    content = html_data['body']['view']['value']
    # 处理获取到的content数据
    # 使用BeautifulSoup解析HTML内容
    return BeautifulSoup(content, 'html5lib')

# 读取Wiki日报表格数据:
table = beaut_table_data(html_data).find_all('table')

涉及BeautifulSoup知识:BeautifulSoup简单用法

3、读取对应日报表格数据

python 复制代码
# 观察Wiki日报结构,发现有个模板表格,所以取第二个table(table[1])
df = pd.read_html(str(table[1]))[0]

涉及pandas知识:https://www.pypandas.cn/docs/getting_started/basics.html

4、获取bug信息

python 复制代码
def get_bug_info(jira_filter, replacements):
    template = Template(jira_filter)
    jira_filter_result = template.substitute(replacements)
    # logger.info(f'jql:{jira_filter_result}')
    jira = ConnectJira.connect_jira()
    issues = jira.search_issues(jira_filter_result, 0, 9999, 1, '', '', '')
    return [f'经办人: {i.fields.assignee}, {i.fields.summary}' for i in issues]

jira_filter = "status in (等待修复, 修复中, 自测中) AND affectedVersion = ${affectedVersion}"
replacements = '1.1.0'
bug_info = get_bug_info(jira_filter, replacements)

涉及JQL知识:JQL语法及Python查询 Jira issue信息

Template使用:Python string模块中Template的substitute()使用

5、拼接日报内容

python 复制代码
    html_data = confluence_read(xxxxx)
    # print(html_data)
    table = beaut_table_data(html_data).find_all('table')
    # print(table[1])
    df = pd.read_html(str(table[1]))[0]
    # print(df)
    process_col_title = ['iOS', 'Android', 'H5/服务端']
    doing = []
    done = []
    affected_versions = []
    replacements = {}
    for index, row in df.iterrows():
        # print(index)
        # print(row)
        if index == 0:
            table_title = row[0].split('(')
            # print(table_title)
            affected_versions.append(table_title[0])
            # print(affected_versions[0])
            replacements = {'affectedVersion': affected_versions[0]}
        if row[0] != '需求名称' and row[0] != '主需求' and index >= 1:
            col_values = [row[i] if not (isinstance(row[i], float) and math.isnan(row[i])) else '' for i in range(3, 6)]
            # print(col_values)
            if not any(col_values) or not any(re.search(pattern, col_value) is not None for col_value in col_values):
                continue
            title_col_value = row[0]
            # print(title_col_value)
            if any(re.search(pattern, col_value) is not None and set(col_value.split(',')) != {'100%'} for col_value in col_values):
                col_values = ['不涉及' if re.search(pattern, i) is None else i for i in col_values]
                # print(col_values)
                doing_rate_info = [f'{process_col_title[i]}-{col_values[i]}' for i in range(len(process_col_title))]
                # print(doing_rate_info)
                doing.append(f'{title_col_value},【进度:{", ".join(doing_rate_info)}】')
            else:
                done.append(title_col_value)
    # print(doing)
    # print(done)
    doing = '\n\n> - '.join(doing)
    done = '\n\n> - '.join(done)
    buglist = '\n\n> - '.join(bug_info) if bug_info else '暂无'
    # print(doing)
    # print(done)

6、钉钉发送日报信息

python 复制代码
def send_dingtalk_message(webhook_url, message, msg_type, title):
    headers = {'Content-Type': 'application/json'}
    if msg_type == 'markdown':
        data = {'msgtype': msg_type, 'markdown': {'title': title, 'text': message}}
    else:
        data = {'msgtype': msg_type, 'text': {'content': message}}
    response = requests.post(url=webhook_url, headers=headers, data=json.dumps(data))

    if response.status_code == 200:
        logger.info("Message sent successfully to DingTalk!")
    else:
        logger.info("Failed to send message to DingTalk")
        logger.info(f"Response status code: {response.status_code}")
        logger.info(f"Response content: {response.text}")

webhook_url获取:钉钉添加自定义机器人,实现每周定时@某人

7、最终效果

使用Markdown格式发送日报:

Markdown 基本语法:https://markdown.com.cn/basic-syntax/

相关推荐
郭庆汝1 小时前
pytorch、torchvision与python版本对应关系
人工智能·pytorch·python
思则变4 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
漫谈网络4 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
try2find6 小时前
安装llama-cpp-python踩坑记
开发语言·python·llama
博观而约取7 小时前
Django ORM 1. 创建模型(Model)
数据库·python·django
精灵vector8 小时前
构建专家级SQL Agent交互
python·aigc·ai编程
Zonda要好好学习8 小时前
Python入门Day2
开发语言·python
Vertira8 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
太凉8 小时前
Python之 sorted() 函数的基本语法
python
项目題供诗9 小时前
黑马python(二十四)
开发语言·python