日报小工具 - 钉钉定时发送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/

相关推荐
java1234_小锋30 分钟前
TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 神经网络基础原理
python·深度学习·tensorflow·tensorflow2
JJJJ_iii32 分钟前
【深度学习03】神经网络基本骨架、卷积、池化、非线性激活、线性层、搭建网络
网络·人工智能·pytorch·笔记·python·深度学习·神经网络
JJJJ_iii40 分钟前
【深度学习05】PyTorch:完整的模型训练套路
人工智能·pytorch·python·深度学习
程序员小远2 小时前
常用的测试用例
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
IT学长编程2 小时前
计算机毕业设计 基于EChants的海洋气象数据可视化平台设计与实现 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
大数据·hadoop·python·毕业设计·课程设计·毕业论文·海洋气象数据可视化平台
辣椒http_出海辣椒2 小时前
Python 数据抓取实战:从基础到反爬策略的完整指南
python
荼蘼2 小时前
使用 Flask 实现本机 PyTorch 模型部署:从服务端搭建到客户端调用
人工智能·pytorch·python
(时光煮雨)2 小时前
【Python进阶】Python爬虫-Selenium
爬虫·python·selenium
小政同学3 小时前
【Python】小练习-考察变量作用域问题
开发语言·python
Lynnxiaowen3 小时前
今天我们开始学习python3编程之python基础
linux·运维·python·学习