乐于分享
好东西不私藏

终于有人把测试报告自动化源码,讲得这么干净透彻!

终于有人把测试报告自动化源码,讲得这么干净透彻!

点击蓝字

关注我们

二、完整源码解析

含结构拆解+函数关系+核心代码示例

上一篇文章《提升测试幸福感:从0到1实现测试报告自动化》梳理了工具的核心逻辑和设计思路,这一部分将深入源码层面,从「整体结构」「函数依赖关系」「核心函数代码实现」三个维度做深度拆解,让大家不仅能看懂「为什么这么设计」,还能看懂「具体怎么实现」,方便后续直接复用、二次开发。

(一)源码整体说明与开发环境

1. 开发环境与依赖库

工具基于 Python3.7+ 开发,兼容性强,任意 Python3 版本均可运行;核心依赖库仅 4 个,均为 Python 常用库,通过 pip 一键安装即可,无复杂环境配置:

tkinter:Python 内置库,无需安装,用于开发桌面可视化界面;

matplotlib:用于生成可视化图表,安装命令:pip install matplotlib

python-docx:用于生成 Word 格式报告,安装命令:pip install python-docx

random:Python 内置库,无需安装,用于生成基础随机数据。

2. 源码整体结构(单文件+单类封装)

源码采用「单文件完整实现」设计(文件名:test_report_tool.py),无多余依赖文件,复制到任意电脑即可运行,轻量化极致。整体结构为「1 个主类 + 7 大功能模块」,所有功能、数据、逻辑都封装在主类中,无全局变量、无零散函数,结构清晰易维护:

# 源码整体结构示意classTestReportAutoTool:    # 【模块1:初始化模块】:程序入口,初始化界面、数据、按钮绑定    def __init__(self, root):        pass    # 【模块2:界面渲染模块】:绘制输入框、按钮、展示区等可视化元素    def _create_input_area(self):  # 输入区域渲染        pass    def _create_button_area(self):  # 按钮区域渲染        pass    def _create_show_area(self):   # 数据展示区域渲染        pass    # 【模块3:基础数据处理模块】:生成、修改、刷新、清空核心数据def generate_data(self):          # 生成基础数据(核心)        pass    def edit_data(self):              # 修改数据入口        pass    def edit_single_module(self, parent):  # 单模块修改        pass    def split_total_data(self, parent):    # 总数据拆分修改        pass    def batch_edit_data(self, parent):     # 批量输入修改(高频)        pass    def refresh_base_data_display(self):   # 数据刷新展示        pass    def clear_data(self):                 # 清空所有数据        pass    # 【模块4:衍生数据计算模块】:计算图表/报告所需的衍生数据    def _calc_module_bug_ratio(self):    # 计算模块缺陷占比        pass    def _calc_bug_level_dist(self):      # 计算缺陷等级分布        pass    def _calc_bug_type_dist(self):       # 计算缺陷类型分布        pass    # 【模块5:图表生成模块】:生成并保存可视化图表    def generate_charts(self):        pass    # 【模块6:报告导出模块】:生成标准化 Word 报告    def download_wps_doc(self):        pass    # 【模块7:辅助工具模块】:通用校验、样式封装、弹窗提示    def _is_system_module(self, module_name):  # 判断是否为系统模块        pass    def _check_positive_int(self, num_str):    # 校验正整数        pass    def _set_table_style(self, table):         # 封装表格样式        pass    def _add_text_to_cell(self, cell, text):   # 单元格文字赋值        pass    def _show_msg(self, title, msg):           # 弹窗提示        pass# 程序运行入口if __name__ == "__main__":import tkinter as tk    root = tk.Tk()    app = TestReportAutoTool(root)    root.mainloop()}

核心设计亮点:所有模块按「业务流程顺序」编写,从上到下阅读完全贴合「初始化→输入→数据处理→输出」的逻辑,新手也能快速定位功能所在位置。

(二)核心模块与函数依赖关系

函数间的依赖关系直接决定了代码的可读性和维护性,本工具的函数设计遵循「低耦合、高内聚」原则,每个模块仅依赖必要的前置模块,无杂乱嵌套。核心依赖关系如下:

1. 核心依赖链路(从初始化到最终输出)

__init__(初始化) → 调用「界面渲染模块」→ 按钮绑定「基础数据处理模块」→ 「基础数据处理模块」提供数据给「衍生数据计算模块」→ 「衍生数据计算模块」+「图表生成模块」提供数据/图表给「报告导出模块」→ 「辅助工具模块」被所有模块调用(通用功能)

2. 关键函数调用关系详解

用「核心功能流程」串联函数,更易理解:

流程1:生成基础数据:点击「生成数据」按钮 → 触发 generate_data() → 内部调用 _is_system_module()(判断模块类型)→ 调用 refresh_base_data_display()(刷新界面展示);

流程2:修改数据:点击「修改数据」按钮 → 触发 edit_data() → 内部调用 edit_single_module()/split_total_data()/batch_edit_data()(三种修改方式)→ 均调用 _check_positive_int()(数据校验)和 refresh_base_data_display()(刷新展示);

流程3:生成报告:点击「导出报告」按钮 → 触发 download_wps_doc() → 内部调用 _calc_module_bug_ratio()/_calc_bug_level_dist()/_calc_bug_type_dist()(计算衍生数据)→ 调用 generate_charts()(生成图表)→ 调用 _set_table_style()/_add_text_to_cell()(排版表格)→ 调用_show_msg()(提示保存成功)。

核心特点:所有函数的调用都围绕「业务流程」展开,每个函数仅负责单一功能,修改任意函数都不会影响其他不相关的功能,易维护、易扩展。

(三)核心函数代码示例与解析

这一部分选取「基础数据生成」「批量数据修改」「图表生成」「报告导出」4个核心函数,提供完整代码示例并做逐行解析,让大家能直接复用核心逻辑。

1. 基础数据生成函数:

generate_data()(数据源头核心)

def generate_data(self):    # 1. 读取用户输入的系统名称和模块名称    self.system_name = self.system_name_entry.get().strip()    module_text = self.module_text.get("1.0", tk.END).strip()    # 校验输入:系统名称和模块名称不能为空    ifnot self.system_name:        self._show_msg("提示""请输入系统名称!")        return    ifnot module_text:        self._show_msg("提示""请输入测试模块名称(每行一个)!")        return    # 2. 解析模块列表:按换行拆分,过滤空行    self.module_list = [module.strip() formodule in module_text.split("\n") ifmodule.strip()]    # 3. 初始化数据容器    self.case_num_dict = {}  # 键:模块名,值:用例数    self.bug_num_dict = {}   # 键:模块名,值:BUG数    self.total_case = 0      # 总用例数    self.total_bug = 0       # 总BUG数    # 4. 遍历模块,差异化生成数据    formodule in self.module_list:        if self._is_system_module(module):            # 系统模块:用例数20-50,BUG数1-5            case_num = random.randint(2050)            bug_num = random.randint(15)        else:            # 业务模块:用例数80-120,BUG数6-20            case_num = random.randint(80120)            bug_num = random.randint(620)        # 存入字典        self.case_num_dict[module] = case_num        self.bug_num_dict[module] = bug_num        # 累加总数        self.total_case += case_num        self.total_bug += bug_num    # 5. 刷新界面展示数据    self.refresh_base_data_display()    self._show_msg("成功"f"基础数据生成完成!\n系统名称:{self.system_name}\n模块数量:{len(self.module_list)}\n总用例数:{self.total_case}\n总BUG数:{self.total_bug}")

解析:

输入校验:先判断系统名称和模块名称是否为空,避免后续逻辑出错,这是代码健壮性的基础;

模块解析:按换行拆分用户输入的模块文本,过滤空行,符合「每行一个模块」的输入习惯;

差异化生成:通过 _is_system_module() 判断模块类型,分别生成不同范围的用例数/BUG数,贴合真实测试场景;

数据汇总:实时累加总用例数和总BUG数,无需后续单独计算,提升效率;

用户反馈:生成完成后通过弹窗提示结果,同时刷新界面展示,用户体验友好。

2. 批量数据修改函数:

batch_edit_data()(高频核心功能)

def batch_edit_data(self, parent):    # parent:父窗口(修改数据窗口),用于后续关闭    module_count = len(self.module_list)    # 1. 新建批量输入窗口    batch_win = tk.Toplevel(parent)    batch_win.title("批量输入用例数/BUG数")    batch_win.geometry("500x300")    # 2. 展示模块顺序(提示用户按此顺序输入)    tk.Label(batch_win, text="模块顺序(请按此顺序用逗号分隔输入):", font=("宋体"10)).grid(row=0, column=0, columnspan=2, pady=5)    module_order = ", ".join(self.module_list)    tk.Label(batch_win, text=module_order, font=("宋体"9), wraplength=450).grid(row=1, column=0, columnspan=2, pady=5)    # 3. 用例数输入框(默认填充当前用例数,便于用户修改)    tk.Label(batch_win, text="用例数(逗号分隔):").grid(row=2, column=0, padx=5, pady=10, sticky="w")    case_entry = tk.Entry(batch_win, width=40)    case_entry.grid(row=2, column=1, padx=5, pady=10)    current_cases = ",".join([str(self.case_num_dict[module]) formodule in self.module_list])    case_entry.insert(0, current_cases)    # 4. BUG数输入框(默认填充当前BUG数)    tk.Label(batch_win, text="BUG数(逗号分隔):").grid(row=3, column=0, padx=5, pady=10, sticky="w")    bug_entry = tk.Entry(batch_win, width=40)    bug_entry.grid(row=3, column=1, padx=5, pady=10)    current_bugs = ",".join([str(self.bug_num_dict[module]) formodule in self.module_list])    bug_entry.insert(0, current_bugs)    # 5. 确认修改按钮逻辑    def confirm():        # 解析用例数:逗号拆分→转整数→校验数量匹配        case_str = case_entry.get().strip()        try:            case_list = [int(num.strip()) for num in case_str.split(","if num.strip()]        except ValueError:            self._show_msg("错误""用例数格式错误!请输入逗号分隔的正整数!")            return        if len(case_list) != module_count:            self._show_msg("错误"f"用例数数量({len(case_list)})与模块数({module_count})不匹配!")            return        # 解析BUG数:同上        bug_str = bug_entry.get().strip()        try:            bug_list = [int(num.strip()) for num in bug_str.split(","if num.strip()]        except ValueError:            self._show_msg("错误""BUG数格式错误!请输入逗号分隔的正整数!")            return        if len(bug_list) != module_count:            self._show_msg("错误"f"BUG数数量({len(bug_list)})与模块数({module_count})不匹配!")            return        # 6. 更新数据        self.total_case = 0        self.total_bug = 0        for i, module in enumerate(self.module_list):            self.case_num_dict[module] = case_list[i]            self.bug_num_dict[module] = bug_list[i]            self.total_case += case_list[i]            self.total_bug += bug_list[i]        # 7. 刷新展示+关闭窗口+提示成功        self.refresh_base_data_display()        batch_win.destroy()        parent.destroy()        self._show_msg("成功""批量修改数据完成!")    # 6. 绘制确认按钮    tk.Button(batch_win, text="确认修改", command=confirm).grid(row=4, column=0, columnspan=2, pady=20)

解析:

界面友好:自动展示模块顺序,默认填充当前数据,用户无需记忆模块顺序,直接修改即可,降低操作成本;

严格校验:先校验输入格式(是否为正整数),再校验数量匹配(输入数量=模块数量),从源头杜绝错误数据;

数据同步:修改后自动更新总用例数/总BUG数,刷新界面展示,确保数据一致性;

窗口管理:修改完成后自动关闭子窗口和父窗口,无需用户手动关闭,体验流畅。

......

本文节选自第八十九期《51测试天地》

原创文章

用Python打造了一款超实用的测试报告神器

文章后续为大家详细讲解了:

源码设计亮点与复用建议总结等

想继续阅读全文

或查看更多《51测试天地》的原创文章

请点击下方 阅读原文或扫描二维码 查看

声明:本文为51Testing软件测试网 M&T. 用户投稿内容,该用户投稿时已经承诺独立承担涉及知识产权的相关法律责任,并且已经向51Testing承诺此文并无抄袭内容。发布本文的用途仅仅为学习交流,不做任何商用,未经授权请勿转载,否则作者和51Testing有权追究责任。如果您发现本公众号中有涉嫌抄袭的内容,欢迎发送邮件至:editor@51testing.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。