
简介微信小程序测试报告Word文档为小程序开发、测试及项目管理人员提供了一套可直接使用或参考的测试文档范例。报告以某商城微信小程序为对象系统梳理了功能、性能、安全、兼容性、UI与用户体验等测试维度的完整流程。资源仅1个Word文档大小23KB内容涵盖测试目的与范围、测试计划执行情况、测试用例执行结果以及安全测试中的软件权限、数据安全、通讯安全等关键要点。报告中还记录了真实测试环境配置不同型号安卓手机、微信版本、MySQL数据库和典型问题如MySQL版本过低导致前端数据未渲染、数据库最初设计不符合三大范式等这些内容可作为实际测试排错的参考。目前已有3971人学习该文档适合需要编写测试报告、规划小程序测试方案或了解测试过程细节的读者可直接修改项目信息后套用有效节省文档撰写时间。1. “可直接使用”是个门槛先想清楚给谁看大多数测试报告写到最后变成“用例执行记录表”领导翻三页找不到结论开发翻十页找不到复现步骤测试自己隔两周再看也忘了当时为什么判定失败。微信小程序测试报告难就难在它跨端、跨工具链页面状态、网络、基础库版本、性能数据揉在一起不整理直接贴出去别人看不懂自己也讲不清。“可直接使用”四个字看起来是交付要求本质上是讲报告不是给测试自己存档的而是给产品、研发、运维和下一轮迭代看的决策资产。它要能回答三个问题——质量过不过关、哪里有问题、优先级怎么排。这篇顺着微信小程序测试报告从数据采集、指标计算到报告生成和防坑验证讲一条能落地的路适合手里已经跑过测试但报告拿不出手的人也适合刚要把小程序测试规范化的团队。2. 数据从哪来先解决采集再谈报告结构2.1 开发者工具自动化用 miniprogram-automator 采集行为数据报告的基础是执行数据。微信小程序测试最常见的执行载体是微信开发者工具自带的自动化能力miniprogram-automator 这个库可以连接工具中打开的项目代替手工点击和输入。比起纯手工记录自动化跑一遍至少能拿到一致的路径、截图和调用链报告里的“执行时间”“步骤结果”才站得住。const automator require(miniprogram-automator) async function run() { // 1. 连接开发者工具中已打开的项目 const miniProgram await automator.launch({ projectPath: /path/to/wechat-mini-program, // 指定基础库版本避免默认版本和线上不一致 baseLibVersion: latest }) // 2. 跳转到目标页面 const page await miniProgram.reLaunch(/pages/index/index) await page.waitFor(500) // 3. 找到按钮并点击模拟真实操作路径 const btn await page.$(.order-btn) await btn.tap() // 4. 采集此时的页面数据和截图 const data await page.data() await page.screenshot({ path: /tmp/report/screenshots/order-submit.png }) // 5. 断开连接 await miniProgram.close() } run().catch(console.error)这段逻辑不复杂关键在三个参数。projectPath必须指向开发者工具导入过的项目根目录不是代码仓库根目录baseLibVersion建议固定到一个发布过的版本不要每轮测试都跟着工具默认值漂移page.waitFor(500)是给异步渲染留缓冲数值根据页面复杂度调粗暴统一设 3 秒反而掩盖渲染性能问题。截图的路径要按用例编号组织报告里引用截图时直接拼相对路径避免后面复制文件时挂链。2.2 真机与云测网络请求和日志的统一收集路径自动化工具覆盖的是可控环境真机上很多问题只有真实网络和真实机型才暴露。真机调试面板里能看到 Network 信息但它没法直接导出结构化数据我一般会在测试阶段给小程序挂一个调试开关把 wx.request 的返回、耗时、状态码统一收集起来。// 在 app.js 中挂一个全局请求拦截测试模式下记录日志 const originalRequest wx.request wx.request function (options) { const startTime Date.now() const report { url: options.url, method: options.method || GET, startTime: new Date().toISOString() } const completeHandler (res) { report.cost Date.now() - startTime report.statusCode res.statusCode // 只在测试模式用上线前要摘掉 if (wx.getStorageSync(test_mode)) { getApp().globalData.requestLogs.push(report) } } return originalRequest({ ...options, success: (res) { completeHandler(res) options.success options.success(res) }, fail: (err) { completeHandler({ statusCode: -1 }) options.fail options.fail(err) } }) }这样真机跑完一轮手工测试后把globalData.requestLogs导出就能看出哪些接口在弱网下超时、哪个域名在特定机型上解析失败。报告里不需要贴整个请求日志但要在问题清单里附上请求耗时和状态码开发定位时不用重新抓包。注意这个拦截只在测试模式开启上线前必须确认开关关闭否则全局改写 wx.request 会影响业务逻辑。2.3 用云函数日志和微信后台数据做二次校验很多团队的小程序后端是微信云开发测试报告里涉及服务端数据时直接从云函数日志拉取执行记录比让开发临时查库快得多。云开发控制台的日志里能看到每次云函数调用的时间、请求参数、返回结果和报错堆栈测试执行时把时间窗口对齐就能把前端截图和堆栈拼起来。这里说一个常见误区报告里写“接口报错”时不要只贴前端红屏截图。前端看到 500根因可能是云函数超时、数据库权限问题、参数格式不对也可能是基础库对 Promise 风格调用的兼容问题。写进报告前至少去云开发控制台看一眼调用日志确认错误发生在哪个环节再决定把问题指派给前端还是后端。这个过程很多人跳过导致测试报告被开发打回“无法复现”本质上不是没法复现是证据链只截了一半。3. 从日志到指标把测试数据变成能支撑结论的数字3.1 三类指标功能通过率、性能基线、缺陷逃逸采集回来的原始数据堆在 JSON 里不会自己说话。测试报告里能直接支撑“可上线”结论的指标我一般分成三类功能执行指标、性能指标、缺陷管理指标。先看一张常用指标对照表后面逐项说明计算口径。指标类别指标名计算方式建议阈值功能执行用例通过率通过用例数 / 总用例数核心流程 ≥ 98%全量 ≥ 95%功能执行核心用例通过率冒烟用例通过数 / 冒烟总数100%有失败即阻断性能首屏渲染耗时页面 onReady 时间 - 页面 onLoad 时间中低端机 ≤ 3s性能setData 耗时占比setData 总耗时 / 页面交互总耗时单次 ≤ 500ms性能内存占用增量操作前后内存差值连续操作 5 次后 ≤ 50MB缺陷缺陷逃逸率线上 Bug 数 / (测试期 Bug 数 线上 Bug 数)≤ 5%功能通过率是最直观的数字但要注意分母怎么定义。全量用例里包含大量重复的边界组合把它们都算进去会把通过率稀释到没有参考意义。我一般是先算出“本轮新增和回归的核心用例通过率”再算全量报告里两个数都写但结论以核心用例为准。性能指标里首屏渲染耗时在小程序里有个隐蔽问题onReady触发并不代表用户看到了有效内容。如果页面上是异步请求回来才渲染列表onReady可能已经跑了但页面还是白屏。计算首屏时间时要么把setData和数据渲染完成作为采集点要么在页面里埋一个显式的“内容已渲染”标记不要直接用生命周期钩子之间的差值糊弄。缺陷逃逸率这个指标需要线上数据配合新项目第一轮测试拿不到这时候报告里写“暂无线上基线”比硬编一个数字更诚实。数据积累几轮后这个指标能反向校准测试用例的质量——如果线上 bug 总是集中在某个模块说明测试设计时对这个模块的覆盖维度不够下一轮要加用例而不是加执行轮次。3.2 用例结果清洗把无意义失败剔除出报告自动化工具跑完一轮原始结果里总有几条失败是不该进入报告统计的。常见的有三类小程序的wx.getSystemInfoSync在新基础库上的 deprecated 警告导致回调时序变化、网络请求偶发超时但重试就能通过、page.waitFor给的缓冲时间不够导致下一画面还没渲染就截图。// 简单的结果清洗逻辑示意 const rawResults [ { id: TC001, status: fail, reason: request timeout after 10s }, { id: TC002, status: fail, reason: element .order-btn not found }, { id: TC003, status: fail, reason: setData error: Converting circular structure to JSON } ] function cleanResults(results) { return results.filter((item) { // 网络超时且同一用例上一轮通过标记为 flaky不算失败 if (item.reason.includes(timeout)) { return false } // 元素未找到要分情况页面结构改动还是渲染未完成 if (item.reason.includes(not found) item.retryCount 2) { return false } return true }) }这段代码的处理思路比代码本身更重要。timeout直接剔除是合理的因为真机和模拟器网络环境差异太大但报告里要单独列一个“不稳定用例”列表连续三轮都超时的用例要反馈给开发查接口性能而不是一直藏在过滤条件里。element not found剔除的条件是“重试两次仍找不到”如果重试后能找到大概率是等待时间不够不是功能缺失。setData的循环引用问题不能剔除这是代码缺陷必须进缺陷清单。3.3 截图和录屏文件如何对应到具体用例测试报告的“可直接使用”很大程度体现在附件组织上。我见过最混乱的报告是把截图全部放在一个文件夹里命名为1.png、2.png正文引用得靠猜。建议截图在采集阶段就按“用例编号-页面名称-操作步骤”命名比如TC001-order-submit-before-click.png然后在报告正文每个步骤后用 Markdown 图片相对路径引用。文件组织方式可以配合 2.1 中的 automation 脚本在执行完每个关键操作后自动截图并重命名。录屏文件体积大报告正文里不要直接嵌视频用表格列出来用例编号、录屏文件路径、视频时长、对应缺陷编号。评审时有人想看再去找录屏不会干扰阅读主流程。4. 报告模板让结论先于数据出现4.1 第一页就该写清楚的三个结论报告最前面应该是结论区只写三件事本轮测试结论通过/有条件通过/未通过、主要风险点、建议上线与否。测试主管或者产品经理看报告通常只给 30 秒能不能在这段时间里抓住重点决定报告被认真对待还是被丢到一边。结论区我一般这样组织测试结论有条件通过 - 核心流程通过率 100%全量通过率 96.2% - 风险点支付回调在弱网环境下偶发 5s 延迟需确认服务端重试机制已生效 - 建议功能层面可上线性能调优项排入下个迭代注意结论和数据的顺序结论在前、数据在后不要在结论区堆名词解释。写风险点时不要只写“存在支付超时风险”要带上复现频率和影响面比如“偶发5 次中 1 次”“影响用户下单支付”。4.2 用例明细表的结构和字段用例明细表是报告主体也是开发看得最多的部分。每一行代表一个用例但字段不要贪多常见做法是控制在十个字段以内字段多会导致维护成本高、漏填率高。用例编号模块用例名称前置条件操作步骤预期结果实际结果优先级状态缺陷编号TC001购物车商品加入购物车已登录点击商品详情页“加入购物车”购物车数量 1符合预期P0通过—TC002购物车删除购物车商品购物车有商品左滑商品点击删除商品从列表消失崩溃退出P0失败BUG-1024操作步骤应该写成别人能照着走一遍的动作序列不要写“验证购物车功能正常”这种无法执行的话。预期结果要可判断比如“购物车角标数字从 0 变 1”比“购物车更新正确”更有用。缺陷编号单独一列和缺陷清单里的编号一一对应便于从用例追到缺陷、从缺陷追回用例。4.3 用 Node 脚本把 JSON 结果直接渲染成 Markdown 报告手工整理几十条用例的表格是重复劳动还容易出错。自动化跑完一轮后结果通常是一份 JSON 或 CSV这时候用脚本生成 Markdown 报告保证数据一致性和排版统一。const results require(./test-results.json) const fs require(fs) function generateReport(results) { const passCount results.filter((r) r.status passed).length const totalCount results.length const rate ((passCount / totalCount) * 100).toFixed(2) const rows results.map((r) { return | ${r.id} | ${r.module} | ${r.name} | ${r.precondition || -} | ${r.steps.replaceAll(;, br)} | ${r.expected} | ${r.actual} | ${r.priority} | ${r.status passed ? 通过 : 失败} | ${r.bugId || -} | }).join(\n) const markdown # 小程序测试报告\n\n## 结论\n- 通过率${rate}%\n\n## 用例明细\n\n| 用例编号 | 模块 | 用例名称 | 前置条件 | 操作步骤 | 预期结果 | 实际结果 | 优先级 | 状态 | 缺陷编号 |\n|---|---|---|---|---|---|---|---|---|---|\n${rows}\n fs.writeFileSync(./report.md, markdown) return rate } const rate generateReport(results) console.log(通过率: ${rate}%)这个脚本的逻辑是把测试执行产生的 JSON 数据按表格模板展开字段从结果文件中读取不需要人工复制粘贴。replaceAll(;, br)是为了让操作步骤在 Markdown 表格里换行显示JSON 里的步骤之间用分号隔开。bugId字段留空时显示为-后续在缺陷清单里单独维护避免报告和缺陷系统数据源冲突。脚本再往后扩展就是支持导出 HTML但 Markdown 版本在微信工作群里沟通已经够用。5. 高频失败原因与验证技巧写进报告前先排除误报5.1 基础库版本截断白屏和组件样式差异先在结论区标注小程序的基础库版本不同页面的渲染表现和 API 支持程度会有差异。测试报告里最常见的“白屏”误报就来自这里测试机基础库版本高自动化模拟器基础库版本低或者反过来某些接口在低版本基础库返回的结果字段不同。写进报告前先在报告的“测试环境”小节里明确列出基础库版本。同一轮测试里自动化环境和真机环境的基础库版本必须一致不一致时生成的结果没有对比意义。遇到白屏时先砍掉网络因素再用两个不同基础库版本分别跑一遍如果只有低版本白屏问题定性为“基础库兼容性缺陷”而不是“页面崩溃”严重级别会降一档处理优先级也不同。5.2 setData 的路径坑错误用法的误报率最高小程序里setData的报错和性能问题在测试报告里出现的频率非常高。常见误用是用字符串路径更新深层嵌套对象比如this.setData({userInfo.nickname: that.data.nickname})这种写法在数据层较浅时没毛病一旦userInfo还没初始化就会报Cannot read property nickname of undefined。自动化工具跑到这一步就标红了但业务代码的写法本身也确实是隐患。写进报告时要区分两种情况一种是数据未定义导致异常属于代码缺陷另一种是 setData 传入的数据量过大导致渲染卡顿页面无响应。前者按缺陷流程走后者需要在报告里附上setData的数据体量和耗时数据性能问题没有截图佐证就很难说服研发去查。5.3 组件方法不存在和滚动失效先重试再定性自动化脚本报component pages/index/index does not have a method navigatorClick这种错误看起来像是页面方法丢了实际经常是小程序组件化框架的事件绑定和页面栈切换导致的时序问题——方法还在只是页面实例的引用没拿到。类似的还有苹果手机在 scroll-view 里滚动不动或者是scroll-view内容高度设置没生效本质是渲染机制差异。处理方式是给这类失败用例加自动重试机制同一用例连跑三次三次都是同一失败原因才定级为失败。报告里对这类用例列出“重试次数”和“失败原因一致性”两个字段让看报告的人能判断这个失败是间歇性问题还是必然缺陷。目前微信小程序的 iOS 端渲染机制和 Android 端有差异很多流程在 Android 能跑通、iOS 就挂重试确认还是失败的就标注“仅 iOS 复现”。5.4 一个验证技巧把失败用例压缩成最小可复现脚本报告里被标为失败的用例提交给研发之前先在本地做一次快速复核。具体做法是把业务路径中的前置动作全省略只保留触发缺陷的最短操作序列单独跑一个最小脚本。比如一个下单支付失败的问题不要保留整个“注册、加购、填地址、提交订单、拉起支付”五步流程直接写一个拉起支付参数固定死的页面看支付回调状态。这个方法能在一小时内帮测试人员过滤掉近半的“无法复现”。很多情况下失败背后是测试数据的脏数据问题或操作顺序问题而不是代码缺陷。经过最小脚本验证仍然失败的问题再进缺陷清单最终报告上的每个失败项都经过二次确认。这样的报告递出去研发不用在本地反复构造数据测试的结论也经得起推敲。本文还有配套的精品资源点击获取