#!/usr/bin/env python3 """生成 UI自动化测试计划.docx""" from docx import Document from docx.shared import Inches, Pt, Cm, RGBColor from docx.enum.table import WD_TABLE_ALIGNMENT from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.enum.section import WD_ORIENT from docx.oxml.ns import qn from docx.oxml import OxmlElement import datetime doc = Document() # ======================== 样式设置 ======================== style = doc.styles['Normal'] style.font.name = '微软雅黑' style.font.size = Pt(10.5) style.element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑') def set_cell_shading(cell, color): shading_elm = OxmlElement('w:shd') shading_elm.set(qn('w:fill'), color) shading_elm.set(qn('w:val'), 'clear') cell._tc.get_or_add_tcPr().append(shading_elm) def add_table_with_header(doc, headers, rows, col_widths=None): table = doc.add_table(rows=1 + len(rows), cols=len(headers)) table.style = 'Table Grid' # Header for i, h in enumerate(headers): cell = table.rows[0].cells[i] cell.text = h cell.paragraphs[0].runs[0].bold = True set_cell_shading(cell, '4472C4') cell.paragraphs[0].runs[0].font.color.rgb = RGBColor(255, 255, 255) # Data for r_idx, row_data in enumerate(rows): for c_idx, val in enumerate(row_data): table.rows[r_idx + 1].cells[c_idx].text = str(val) if col_widths: for i, w in enumerate(col_widths): for row in table.rows: row.cells[i].width = Cm(w) return table # ======================== 封面 ======================== doc.add_paragraph() doc.add_paragraph() title = doc.add_paragraph() title.alignment = WD_ALIGN_PARAGRAPH.CENTER run = title.add_run('SwitchBot App UI自动化测试计划') run.font.size = Pt(26) run.bold = True doc.add_paragraph() subtitle = doc.add_paragraph() subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER run = subtitle.add_run('单品设备功能测试 + 设备添加 + 自动化场景') run.font.size = Pt(14) run.font.color.rgb = RGBColor(68, 114, 196) doc.add_paragraph() doc.add_paragraph() info = doc.add_paragraph() info.alignment = WD_ALIGN_PARAGRAPH.CENTER info.add_run(f'版本: v1.0\n').font.size = Pt(11) info.add_run(f'日期: {datetime.date.today().strftime("%Y-%m-%d")}\n').font.size = Pt(11) info.add_run('部门: 测试部\n').font.size = Pt(11) doc.add_page_break() # ======================== 1. 项目概述 ======================== doc.add_heading('1. 项目概述', level=1) doc.add_heading('1.1 背景', level=2) doc.add_paragraph( 'SwitchBot App 涵盖 100+ 款 IoT 设备,需要对每款设备的 App 功能进行自动化回归测试。' '本计划基于已验证的 Vitest + Appium 技术框架,按优先级分层推进:' '必测项 → 单品探索 → 全功能 → 平台,高优先级层先达标再投入下一层。' ) doc.add_heading('1.2 技术栈', level=2) rows = [ ('框架', 'Vitest (TypeScript) + Appium'), ('驱动', 'UIAutomator2 (Android) / WebDriverAgent (iOS)'), ('AI辅助', 'Claude Code 边跑边写生成 & 调试脚本'), ('测试设备', 'Samsung 1080x2280 (Android) / iPhone 390x844pt (iOS)'), ('App', 'SwitchBot (com.theswitchbot.switchbot)'), ('报告', '自定义 HTML 报告 + JSON 结果'), ('用例管理', 'ONES 平台同步'), ] add_table_with_header(doc, ['项目', '说明'], rows) doc.add_heading('1.3 当前进度', level=2) doc.add_paragraph('已调试完成的设备(不在本计划范围内):') rows = [ ('Bot', '5', '卡片/控制/设置/场景/日志', '100%'), ('Camera (Pan/Tilt Plus 3K)', '6', '卡片/控制/全屏/事件/录像/设置', '100%'), ('AI Hub', '11', '设置/投屏/侦测/勿扰/存储/回放/AI事件/日报/功能页/连接/绑定', '86%'), ] add_table_with_header(doc, ['设备', '脚本文件数', '覆盖模块', '通过率'], rows) doc.add_heading('1.4 目标', level=2) doc.add_paragraph('• P0 必测项:各单品添加 + 核心控制(双协议)准入闸门,来源 ONES 必测项-AI自动化') doc.add_paragraph('• P1 单品探索:82 款单品主流程冒烟,覆盖广度') doc.add_paragraph('• P2 全功能:全维度回归(card/control/setting/scene/logs),覆盖深度') doc.add_paragraph('• P3 平台:账号/房间/消息/家庭分享/场景等平台功能') doc.add_paragraph('• 按优先级 backlog 依次交付,各层有独立退出标准(不绑定固定周次)') doc.add_page_break() # ======================== 2. 设备清单 ======================== doc.add_heading('2. 待覆盖设备清单(82款)', level=1) device_categories = { '窗帘 (9款)': [ ('Curtain Rod', '已有脚本', '调试适配'), ('Curtain Rod 2', '已有脚本', '调试适配'), ('Curtain U Rail', '已有脚本', '调试适配'), ('Curtain U Rail 2', '已有脚本', '调试适配'), ('Curtain U Rail 2.3', '复用模板', '新增配置'), ('Curtain 3 U Rail', '复用模板', '新增配置'), ('Curtain 3 Rod 2025', '复用模板', '新增配置'), ('Curtain 4 Urail', '复用模板', '新增配置'), ('Roller Shade', '复用模板', '新增配置'), ], '锁 (12款)': [ ('Lock (JP)', '已有脚本', '调试适配'), ('Lock (US)', '已有脚本', '调试适配'), ('Lock (EU)', '复用模板', '新增配置'), ('Lock Pro (EU)', '复用模板', '新增配置'), ('Lock Pro (US)', '复用模板', '新增配置'), ('Lock Lite', '复用模板', '新增配置'), ('Lock Ultra (JP)', '需新写', 'UI差异大'), ('Lock Ultra (US)', '需新写', 'UI差异大'), ('Lock Ultra (EU)', '需新写', 'UI差异大'), ('Lock Pro Matter Enabled', '复用模板', '新增配置'), ('US Vision Deadbolt Pro', '需新写', '全新UI'), ('US Vision Deadbolt', '需新写', '全新UI'), ], '灯光 (10款)': [ ('LED Strip Light 2', '已有脚本', '调试适配'), ('Strip Light 3', '已有脚本', '调试适配'), ('RGBICWW Strip Light', '复用模板', '新增配置'), ('RGBICWW Floor Lamp', '复用模板', '新增配置'), ('RGBIC Neon Rope Light', '复用模板', '新增配置'), ('RGBIC Wire Neon Rope Light', '复用模板', '新增配置'), ('RGBICWW Ceiling Light', '已有脚本', '调试适配'), ('Floor Lamp', '复用模板', '新增配置'), ('Candle Lamp', '复用模板', '新增配置'), ('Permanent Outdoor Lights', '需新写', '户外新品'), ], '插座+开关 (6款)': [ ('Plug Mini (JP) HomeKit Enabled', '已有脚本', '调试适配'), ('Plug Mini (US) HomeKit Enabled', '已有脚本', '调试适配'), ('Plug Mini (EU)', '复用模板', '新增配置'), ('Relay Switch 1', '已有脚本', '调试适配'), ('Relay Switch 1PM', '复用模板', '新增配置'), ('Relay Switch 2PM', '复用模板', '新增配置'), ], '扫地机 (9款)': [ ('Robot Vacuum Cleaner S1', '已有脚本', '调试适配'), ('Robot Vacuum Cleaner S1 Plus (W)', '已有脚本', '调试适配'), ('Mini Robot Vacuum K10+Pro', '复用模板', '新增配置'), ('Robot Vacuum K20+ Pro', '需新写', '新一代UI'), ('Robot Vacuum K10+ Pro Combo', '复用模板', '新增配置'), ('Robot Vacuum K11+', '需新写', '新一代UI'), ('Robot Vacuum K11+ Pro', '需新写', '新一代UI'), ('Floor Cleaning Robot S20', '需新写', '全新UI'), ('Floor Cleaning Robot S20 Mini', '需新写', '全新UI'), ], '传感器+温控 (7款)': [ ('Indoor/Outdoor Thermo-Hygrometer', '已有脚本', '调试适配'), ('Meter Pro', '已有脚本', '调试适配'), ('Meter Pro (CO2 Monitor)', '复用模板', '新增CO2功能'), ('Water Leak Detector with Sensor Cable', '已有脚本', '调试适配'), ('Presence Sensor', '需新写', '全新UI'), ('Home Climate Panel', '需新写', '全新UI'), ('Weather Station', '需新写', '全新UI'), ], '风扇+空净+加湿器 (6款)': [ ('Circulator Fan', '已有脚本', '调试适配'), ('Standing Circulator Fan', '复用模板', '新增配置'), ('Circulator Fan Pro', '复用模板', '新增配置'), ('Air Purifier', '需新写', '全新品类'), ('Air Purifier Table', '需新写', '全新品类'), ('Evaporative Humidifier (Auto-refill)', '已有脚本', '调试适配'), ], '摄像头+门铃 (3款)': [ ('Pan/Tilt Cam 3MP猫狗定制款', '复用camera', '调试适配'), ('Video Doorbell', '需新写', '门铃UI差异'), ('OSC KVS', '已有脚本', '调试适配'), ], '网关Hub (3款)': [ ('Hub 3', '已有脚本', '调试适配'), ('AI Hub', '已完成', '—'), ('AI Hub Show', '需新写', '带屏新品'), ], '门控+安防+配件 (5款)': [ ('Keypad Vision', '已有脚本', '调试适配'), ('Keypad Vision Pro', '复用模板', '新增配置'), ('Garage Door Opener', '需新写', '全新品类'), ('Safety Alarm', '需新写', '全新品类'), ('Smart Radiator Thermostat', '需新写', '全新品类'), ], 'AI产品 (5款)': [ ('Art Frame', '需新写', '全新UI框架'), ('Art Frame luma', '需新写', '全新UI框架'), ('AI Pet', '需新写', '全新品类'), ('AI PinNote', '需新写', '全新品类'), ('Bot Rechargeable', '复用bot', '调试适配'), ], '机器人+联名+其他 (8款)': [ ('OBBOTO 1.0', '需新写', '全新品类'), ('Robotic Actuator', '需新写', '全新品类'), ('Robotic Arm', '需新写', '全新品类'), ('Robotic Picker', '需新写', '全新品类'), ('SwitchBot KATAフレンズ KUMAMON ver.', '复用bot', '特殊UI定制'), ('KATA Friends 国行版', '复用bot', '特殊UI定制'), ('Outdoor PTC', '需新写', '全新品类'), ('FindCard', '已有脚本', '调试适配'), ], } for cat_name, devices in device_categories.items(): doc.add_heading(cat_name, level=2) add_table_with_header(doc, ['设备名称', '脚本状态', '备注'], devices, col_widths=[6, 3, 4] ) doc.add_paragraph() doc.add_page_break() # ======================== 3. 测试维度说明 ======================== doc.add_heading('3. 测试维度说明', level=1) doc.add_paragraph('每款设备根据功能复杂度,覆盖以下测试维度。人力预估基于 AI 辅助(Claude Code 边跑边写):首台需建模分析,同品类复用台仅改配置,工时约减半或更低。') rows = [ ('card', '{device}_card.test.ts', '首页卡片展示与交互', '3-5', 'P1 / P2', '0.3 / 0.1'), ('control', '{device}_control.test.ts', '功能页核心操作(开关/模式/参数调节)', '8-20', 'P0 / P1 / P2', '1.0 / 0.3'), ('setting', '{device}_setting.test.ts', '设备设置页(名称/房间/固件/信息)', '5-8', 'P2', '0.5 / 0.2'), ('connect', '{device}_connect.test.ts', '设备添加/配对流程', '3-5', 'P0 / P2', '0.5 / 0.2'), ('scene', '{device}_scene.test.ts', '自动化/场景联动', '3-8', 'P3', '0.5 / 0.2'), ('logs', '{device}_logs.test.ts', '操作日志查看', '2-4', 'P2(可选)', '0.2 / 0.1'), ] add_table_with_header(doc, ['维度', '文件命名', '内容', '用例数', '优先级层', 'AI预估(人日:首台/复用)'], rows, col_widths=[1.3, 3.8, 4.2, 1.2, 2, 3] ) doc.add_paragraph() doc.add_paragraph('用例数量估算:每设备平均 25-40 条,82款设备总计约 2000-3000 条自动化用例。') doc.add_paragraph('AI 提效口径:单维度脚本首台 0.2-1 人日、复用台 0.1-0.3 人日;串口添加框架为一次性投入(见 §5.2)。下列各层人力预估均按此口径,单位为人日(1 人)。') doc.add_page_break() # ======================== 4. 测试优先级分层 ======================== doc.add_heading('4. 测试优先级分层', level=1) doc.add_paragraph( '本计划按优先级分四层推进,依次为:必测项 → 单品探索 → 全功能 → 平台。' '高优先级层先达标再投入下一层;不绑定固定周次,按相对工作量排 backlog。' ) rows = [ ('P0 必测项', '各单品添加 + 核心控制(双协议)', 'ONES 必测项-AI自动化 (CQz9YCNX)', '187', '每次提测/版本必跑', '通过率≥95%'), ('P1 单品探索', '每单品主流程冒烟(card+核心control)', '按单品模板', '82款各1遍', '每迭代', '全单品冒烟通过'), ('P2 全功能', '全维度回归(card/control/setting/scene/logs)', '各品类用例库', '~2366', '版本回归', '通过率≥85%'), ('P3 平台', '账号/房间/消息/家庭分享/场景等平台功能', 'App平台用例库', '平台模块', '版本回归', '平台用例通过'), ] add_table_with_header(doc, ['优先级', '范围', '来源', '用例量', '运行频率', '退出标准'], rows, col_widths=[2.2, 4, 3.5, 1.3, 2.5, 2.5] ) doc.add_page_break() # ======================== 5. P0 必测项 ======================== doc.add_heading('5. P0 必测项(最高优先)', level=1) doc.add_paragraph( '必测项是提测/版本更新的准入闸门,来源 ONES 测试计划「必测项-AI自动化」(plan CQz9YCNX / lib EPfZfC9Y),' '映射清单见 test-plan/must-test.manifest.ts,转换规则见 prompts/must_test_conversion.md。' ) doc.add_heading('5.1 必测项构成', level=2) rows = [ ('添加 (connect)', '每单品型号一条「添加X验证」', '73', 'connect 维度,需串口配合'), ('单品功能 (feature)', '绑定手持/学习遥控器/keypad密码指纹/温湿度单位等', '9', 'control/setting 维度'), ('控制 (control)', '2条协议超级用例逐 step:BLE 49 + WiFi 56', '105', 'control 维度,双协议各跑一遍'), ] add_table_with_header(doc, ['类型', '说明', '条数', '落点/备注'], rows) doc.add_paragraph() p = doc.add_paragraph() p.add_run('合计:').bold = True p.add_run('187 条(另 2 条 na:safety alarm 无目录、强绑定解绑归平台)。控制粒度在 step,按 (用例号#step)+协议精确回写 ONES。') doc.add_heading('5.2 前置:设备添加自动化(关键路径,最先启动)', level=2) doc.add_paragraph( '必测含 73 条添加,添加流程需硬件配合(串口控制设备进入配对模式),分 BLE 直连与 Wi-Fi 配网两种模式。' '此为 P0 第一阻塞项,须最先启动;控制部分(无需串口)可并行先行。' ) rows = [ ('串口命令协议文档', '统一所有设备“进入配对模式”的串口指令', '嵌入式+测试'), ('串口控制模块', 'serial_controller.ts (基于 serialport库)', '测试'), ('添加流程通用框架', 'connect_base_helper.ts', '测试'), ('Wi-Fi 配网模块', 'wifi_connect_helper.ts', '测试'), ('硬件环境', 'USB Hub + USB转TTL × 5-10', '测试'), ] add_table_with_header(doc, ['任务', '输出', '负责'], rows) doc.add_paragraph() p = doc.add_paragraph() p.add_run('框架一次性投入:').bold = True p.add_run('serial_controller + connect_base_helper + wifi_connect_helper ≈ 1-1.5 人日纯代码(serial 基于现成桌面 serialport 工具薄封装、add 流程复用现有 addDeviceViaBLE,仅 wifi 配网 helper 需新写)。硬件联调(USB-TTL 接线/端口/时序)由嵌入式主导,为 wall-clock 不确定项,不计入纯人日。') doc.add_paragraph( '关键:添加流程 app 侧通用,逐设备差异仅为“开发版上进入配对模式的按键/串口指令”,由嵌入式提供的「设备→串口键」配置表驱动,逐设备近乎零编码。' 'app 侧只需按类别区分设置步骤(BLE 直连 / Wi-Fi 配网 / 带屏 / 锁含校准),约 4-5 类,而非 73 份脚本。' ) doc.add_heading('5.3 添加 backlog(通用流程 + 配置表驱动)', level=2) rows = [ ('首验', 'BLE直连(Bot/Meter/Sensor) + Wi-Fi配网框架打通', '端到端 demo', '0.5'), ('BLE 直连类', '窗帘/传感器/风扇/遥控器/插座开关/灯 等', '设备→串口键配置 + 验证', '1'), ('Wi-Fi 配网类', 'Hub/摄像头/扫地机 等(额外配网步骤)', '配网流程 + 配置', '1.5'), ('带屏 / 锁类', 'AI Hub Show / Lock 系列(含校准)', '类别专属设置步骤', '1.5'), ] add_table_with_header(doc, ['批次', '范围', '交付物', 'AI预估(人日)'], rows) doc.add_paragraph('添加小计:约 4-6 人日(流程通用、按 4-5 类区分;逐设备仅配置串口键,成本主要在逐台硬件验证的 wall-clock,非人日)。') doc.add_heading('5.4 控制 backlog(双协议,105 step)', level=2) doc.add_paragraph('• 协议为运行模式:PROTO=ble(关WiFi/热点、开蓝牙)/ PROTO=wifi(开WiFi/热点、关蓝牙),各跑一遍。') doc.add_paragraph('• camera/robot/osc 仅 WiFi;Bot/Lock/Curtain/Meter 等两协议都覆盖。') doc.add_paragraph('• 控制内容含开关/开锁/百分比/meter温湿度校正/camera出流3min/robot清扫暂停回充/Humidifier2绑温湿度计。') doc.add_paragraph('• 结果按 [ONES:号#step][协议] 锚点 step 级回写 plan CQz9YCNX。') doc.add_paragraph('控制小计:约 3-4 人日(大部分品类已有 _control 用例 → P0 主要是给既有断言打 [P0][#step][协议] 锚点 + 双协议切换 harness ~1 人日 + 补少量缺口;双协议第二遍仅切前置、增量低)。') doc.add_paragraph() p = doc.add_paragraph() p.add_run('P0 合计:').bold = True p.add_run('约 11-15 人日(串口框架~1-1.5 + 添加 4-6 + 控制 3-4 + 功能9条~3 + step回写工具~0.5)。控制大部分品类已有 _control 用例可复用,主要是打锚点 + 双协议 harness;功能 9 条为 keypad 密码指纹/学习遥控/绑定手持等较复杂项;硬件联调由嵌入式主导,单列不计入。') doc.add_page_break() # ======================== 6. P1 单品探索 ======================== doc.add_heading('6. P1 单品探索(覆盖广度)', level=1) doc.add_paragraph( '必测项达标后,为全部 82 款单品各跑通一遍主流程冒烟,确保每款设备最低限度可用。' '范围 = card(首页卡片)+ 核心 control(开关/主模式),不含设置/场景/日志等深度回归。' ) doc.add_paragraph('• 目标:82 款单品各 1 套冒烟,广度优先、深度浅。') doc.add_paragraph('• 复用必测项已建的 control helper,单品只补 card 与主流程断言。') doc.add_paragraph('• 退出标准:每款单品冒烟用例通过(card 可见 + 核心控制响应)。') doc.add_paragraph('• 运行频率:每迭代跑一遍,作为单品级回归基线。') doc.add_paragraph('• 人力预估(AI 辅助):约 12-16 人日(建立在 P0 已建 control helper 之上,82 款多为同品类复用,首台 ~0.3、复用台 ~0.1 人日/款)。') doc.add_page_break() # ======================== 7. P2 全功能 ======================== doc.add_heading('7. P2 全功能(深度回归)', level=1) doc.add_paragraph( '对每款单品做全维度回归(card/control/setting/scene/logs)。按品类批量推进:' '同品类 UI 高度相似,调通首台后改设备名配置快速扩展,并沉淀通用 helper。' '不绑定周次,按复用度从高到低排批次。' ) rows = [ ('批1·高复用', '窗帘9 / 锁12 / 插座开关6 / 灯光10', '37', '脚本×37 + curtain/lock/relay/light helper', '~25'), ('批2·中复杂', '扫地机9 / 传感器温控7 / 风扇空净加湿6 / 摄像头门铃3', '25', '脚本×25 + robot/sensor/climate helper', '~27'), ('批3·新品特殊', 'Hub门控安防5 / AI产品5 / 机器人联名5', '15+', '脚本×15 + 全新UI框架', '~28'), ] add_table_with_header(doc, ['批次', '品类', '设备数', '交付物', 'AI预估(人日)'], rows, col_widths=[2.3, 5, 1.3, 5, 2.2] ) doc.add_paragraph() p = doc.add_paragraph() p.add_run('覆盖目标:').bold = True p.add_run('全部 82 款单品全维度回归,~2366 条用例,单品功能覆盖率 100%。') p = doc.add_paragraph() p.add_run('P2 合计:').bold = True p.add_run('约 75-90 人日(仅 card/control/setting 约 60-70,含 scene/logs 约 75-90)。约 50 款为“已有/复用”可低成本适配;真正“需新写”的新品 UI 约 30 款(扫地机新机/Lock Ultra·Vision/AI产品/机器人)需 Figma/UX 重新分析,AI 辅助有限、为主要成本;add/control 已被 P0/P1 覆盖可复用。') doc.add_heading('7.1 高复用品类要点', level=2) doc.add_paragraph('• 窗帘: 位置控制、校准流程、定时器、群组控制 → curtain_helper') doc.add_paragraph('• 锁: 密码管理、开锁方式切换、自动锁定、电量监控 → lock_helper') doc.add_paragraph('• 插座开关: 开关、定时器、功率/电量统计、过载保护 → relay_helper') doc.add_paragraph('• 灯光: RGB颜色、亮度、模式切换、渐变 → light_helper') doc.add_heading('7.2 中复杂品类要点', level=2) doc.add_paragraph('• 扫地机: 地图管理/禁区/多楼层、清扫模式、自清洁基站(地图画布操作为难点)') doc.add_paragraph('• 传感器+温控: 温湿度展示、历史图表、告警、灵敏度(图表验证需截图/文本提取)') doc.add_paragraph('• 风扇+空净+加湿: 风速/模式/摇头/定时、空气质量/滤网、湿度目标/水箱') doc.add_paragraph('• 摄像头+门铃: 出流/录像/事件、门铃呼叫/访客/对讲、OSC 复用') doc.add_heading('7.3 新品+特殊要点', level=2) doc.add_paragraph('• Hub 3 / AI Hub Show: 设备管理、红外学习、Matter、带屏交互') doc.add_paragraph('• 门控安防: Garage Door、Safety Alarm、Radiator Thermostat') doc.add_paragraph('• AI产品: Art Frame、AI Pet、AI PinNote(全新UI,需从Figma/UX重新分析)') doc.add_paragraph('• 机器人+联名: OBBOTO、Robotic Actuator/Arm/Picker、KATA Friends(Bot复用+定制皮肤)') doc.add_page_break() # ======================== 8. P3 平台 ======================== doc.add_heading('8. P3 平台功能', level=1) doc.add_paragraph( '单品三层达标后,覆盖跨单品的平台级功能(必测项中约 12 条平台项 + 平台用例库)。' ) doc.add_heading('8.1 平台功能范围', level=2) rows = [ ('账号', '注册/登录/登出/忘记密码/第三方登录/欧区账号', '账号2.0'), ('家庭与房间', '创建房间、家庭分享3.0、家庭分组', '分享/分组用例库'), ('消息与商城', '消息中心3.0、商城、我的、小组件', '对应平台库'), ('其他', '覆盖安装、插件热更、第三方服务接入', 'App必测项平台模块'), ] add_table_with_header(doc, ['模块', '内容', '来源'], rows) doc.add_heading('8.2 自动化/场景联动', level=2) doc.add_paragraph('验证设备间联动可靠性(复用已有 automation 脚本基础):') doc.add_paragraph('• 创建自动化:手动/条件触发/定时触发') doc.add_paragraph('• 执行验证:触发条件满足后动作执行') doc.add_paragraph('• 编辑/删除:修改条件或动作、删除自动化') doc.add_paragraph('• 多设备联动:A设备触发 → B设备执行') doc.add_paragraph('• 异常处理:设备离线时的自动化表现') doc.add_page_break() # ======================== 8. 资源需求 ======================== doc.add_heading('9. 资源需求汇总', level=1) doc.add_heading('9.1 人力与分工', level=2) rows = [ ('自动化测试工程师', '1人', '全职、全程,承担全部脚本编写与调试'), ('嵌入式工程师(配合)', '按需', '提供串口协议与配对框架支持(P0 添加阻塞项),最优先'), ('AI辅助 (Claude Code)', '—', '边跑边写生成+调试脚本,贯穿全程提效'), ] add_table_with_header(doc, ['角色', '人数', '说明'], rows) doc.add_paragraph() doc.add_paragraph( '人力安排:仅 1 名自动化工程师,四层按优先级串行推进,AI 辅助提效。' 'P0 内部拆两条轨——「控制轨」不依赖串口可先行,「添加轨」待嵌入式串口框架就绪后插入,两轨由同一人分时推进。' ) rows = [ ('P0 · 控制轨', '自动化(1人)', '—', '先行:双协议控制 105 step,不待串口'), ('P0 · 添加轨', '自动化(1人)', '嵌入式(串口协议+框架)', '串口就绪后插入:73 添加 + 9 功能'), ('P1 单品探索', '自动化(1人)', '—', 'P0 达标后:82 款冒烟'), ('P2 全功能', '自动化(1人)', '—', '按品类批量,复用 helper'), ('P3 平台', '自动化(1人)', '—', '最后:平台功能 + 场景联动'), ] add_table_with_header(doc, ['优先级层', '主负责', '配合', '安排说明'], rows, col_widths=[2.5, 2.5, 3.5, 6] ) doc.add_heading('9.2 硬件设备', level=2) doc.add_paragraph('每品类至少需要1台实体设备用于调试和验证:') rows = [ ('P0 串口硬件', 'USB Hub + USB转TTL×5-10、开发版设备', '最先到位(添加为关键路径)'), ('P0/P1 必测+冒烟', '必测涉及的各品类代表设备各1台', '随 P0 启动'), ('P2 高复用', '窗帘×1, 锁×2, 插座×1, 开关×1, 灯×3', '全功能批1前到位'), ('P2 中复杂', '扫地机×2, 传感器×3, 风扇×1, 空净×1, 加湿器×1, 门铃×1', '全功能批2前到位'), ('P2 新品特殊', 'Hub 3, AI Hub Show, Art Frame, AI Pet等', '全功能批3前到位'), ] add_table_with_header(doc, ['用途', '设备需求', '到位时间'], rows) doc.add_heading('9.3 环境', level=2) rows = [ ('测试手机', 'Samsung (Android) + iPhone (iOS)', '已有'), ('Appium Server', 'v2.x + UIAutomator2', '已有'), ('网络环境', '稳定Wi-Fi (Deco)', '已有'), ('CI/CD', 'Jenkins/GitHub Actions (可选)', '待搭建'), ] add_table_with_header(doc, ['项目', '说明', '状态'], rows) doc.add_page_break() # ======================== 10. 优先级 backlog 一览 ======================== doc.add_heading('10. 优先级 backlog 一览', level=1) rows = [ ('P0 必测项', '添加73 + 功能9 + 控制105step(双协议)', '187条', '~11-15', 'serial框架 + connect + 控制断言 + step回写', '通过率≥95%'), ('P1 单品探索', '82款单品主流程冒烟(card+核心control)', '82款×1', '~12-16', '每单品冒烟用例', '全单品冒烟通过'), ('P2 全功能', '全维度回归,按品类批量(高复用→新品)', '~2366条', '~75-90', '85+脚本 + 8个通用helper', '通过率≥85%、覆盖100%'), ('P3 平台', '账号/房间/消息/家庭分享/场景等', '平台模块', '~12-15', '平台用例 + 场景联动', '平台用例通过'), ] add_table_with_header(doc, ['优先级', '范围', '用例量', 'AI预估(人日)', '交付物', '退出标准'], rows, col_widths=[2, 4.3, 1.5, 2, 4.2, 2.5] ) doc.add_paragraph() p = doc.add_paragraph() p.add_run('人力总计(AI 辅助口径):').bold = True p.add_run('约 105-135 人日 ≈ 5-7 人月(1 人,按 20 人日/月)。P0 大幅复用既有 control、串口硬件联调由嵌入式主导不计入;P2 “需新写”新品 UI 占比最高、最不可压缩。') doc.add_paragraph( '人力构成说明:以上为 AI 辅助口径(较手工已下调约 2-3 倍)。其中“脚本编写”仅占约 1/3——AI 提效主要在此;' '其余约 2/3 是真机调试(元素核对、加载等待、flaky 复跑)、设备/硬件配置与新品 UI 分析,受真机往返与 UI 稳定性约束,AI 难以进一步压缩。' '项目使用 Midscene(AI 元素定位)已减少传统选择器维护成本,故未再按“零调试”乐观值估算。' '若需再压缩周期,杠杆在于:多台真机并行、收窄 P2 范围(只保高频设备)、放宽 flaky 容忍度,而非提高编写速度。' ) doc.add_paragraph() p = doc.add_paragraph() p.add_run('说明:').bold = True p.add_run('按优先级依次交付,高层达标后投入下一层;不绑定固定周次。P0 控制部分可不待串口先行,添加随串口框架就绪推进。') doc.add_page_break() # ======================== 10. 质量标准 ======================== doc.add_heading('11. 质量标准与验收', level=1) doc.add_heading('11.1 单设备验收标准', level=2) doc.add_paragraph('• 核心用例通过率 ≥ 85%(首轮调试)') doc.add_paragraph('• 单次全量执行时间 < 10分钟/设备') doc.add_paragraph('• 用例覆盖:card + control + setting 三个维度必须覆盖') doc.add_paragraph('• 脚本可在 Android/iOS 双平台运行(通过平台适配层)') doc.add_heading('11.2 优先级层验收标准', level=2) rows = [ ('P0 必测项', '187条全部实现并跑通(添加+控制双协议)', '通过率≥95%,作为提测门禁'), ('P1 单品探索', '82款单品冒烟全部通过', '广度100%覆盖'), ('P2 全功能', '全维度回归,通过率≥85%', '单品功能覆盖率100%'), ('P3 平台', '平台功能 + 场景联动通过', '全流程覆盖'), ] add_table_with_header(doc, ['优先级', '验收标准', '覆盖目标'], rows) doc.add_heading('11.3 回归策略', level=2) doc.add_paragraph('• P0 必测项:每次提测/版本更新必跑(双协议),作为准入门禁') doc.add_paragraph('• P1 单品探索:每迭代执行一遍全单品冒烟') doc.add_paragraph('• P2 全功能:版本回归执行累计设备全量') doc.add_paragraph('• P3 平台:版本回归执行平台功能与场景联动') doc.add_page_break() # ======================== 11. 风险与依赖 ======================== doc.add_heading('12. 风险与依赖', level=1) doc.add_heading('12.1 关键依赖', level=2) rows = [ ('串口/添加为关键路径(前移)', '高', '硬件或协议不就绪将阻塞 P0 整体', '控制部分(无需串口)先行,串口框架并行启动'), ('实体设备到位', '高', '无设备无法调试', 'P0 涉及的代表设备最先准备'), ('嵌入式串口协议', '高', '直接影响 P0 添加', '最优先启动协议定义'), ('同品类UI一致性', '中', 'UI差异大则无法复用', '差异设备单独排期'), ('新品UI稳定', '高', 'UI仍在迭代会导致返工', '等UI冻结后再开始(主要影响P2新品)'), ('App版本稳定', '中', '频繁改版影响脚本维护', '锁定测试版本'), ] add_table_with_header(doc, ['依赖项', '风险等级', '影响', '缓解措施'], rows) doc.add_heading('12.2 待讨论问题', level=2) doc.add_paragraph('1. 设备添加的串口开发版/协议时间线?(决定 P0 添加何时能启动)') doc.add_paragraph('2. 必测项控制双协议环境切换(开关WiFi/蓝牙)能否用 adb/串口自动化,还是需人工配合?') doc.add_paragraph('3. 已下市产品(Hub Plus、老灯带、加湿器1等)是否纳入 P2 全功能?') doc.add_paragraph('4. 同一设备的不同区域版本(JP/US/EU)UI差异程度?是否需逐个调试?') doc.add_paragraph('5. CI/CD 持续集成环境是否需要在 P0 之前搭建?') # ======================== 保存 ======================== output_path = '/Users/woan/Desktop/AI_UIAutomation/docs/UI自动化测试计划.docx' doc.save(output_path) print(f'✓ 文档已生成: {output_path}')