
文章目录微信小程序测试一、小程序是怎么跑起来的1.1 双线程架构1.2 小程序的生命周期1.3 小程序的技术限制二、功能测试每个组件拆开来看2.1 导航与页面跳转2.2 用户授权体系2.3 表单组件2.3.1 input 输入框2.3.2 textarea 多行输入2.3.3 picker 选择器2.3.4 switch / slider / radio / checkbox2.4 数据缓存 Storage2.5 支付流程三、兼容性测试想教育普通APP多了一个维度3.1 三轴兼容矩阵3.2 基础库版本对 API 的影响3.3 iOS 和 Android 的渲染差异3.4 实际手机测试 checklist四、性能测试包大小 运行时4.1 包体积优化与检测4.2 启动性能4.3 运行时性能4.4 体验评分工具五、安全测试5.1 数据传输安全5.2 用户数据安全5.3 代码反编译与防护5.4 越权与注入六、自动化测试6.1 minium微信官方测试框架6.2 Airtest更简单的小程序自动化6.3 微信云测服务七、常见问题与解决方案速查八、小程序测试检查清单微信小程序测试一、小程序是怎么跑起来的做小程序测试之前必须先理解它的运行机制。否则很多看起来是bug的现象其实是架构限制很多测了也没用的用例也是在浪费精力。1.1 双线程架构微信小程序的运行环境由三个部分组成渲染层View和逻辑层App Service是分离的它们之间通过微信客户端的 Native 桥进行通信。这意味着JS 代码不能直接操作 DOM和浏览器不同数据更新必须通过setData()从逻辑层传到渲染层setData()是有成本的——数据量大或调用频繁会直接导致页面卡顿渲染层的 WebView 在 iOS 上是 WKWebView在 Android 上是 X5 内核或系统 WebView——两者行为不完全一致测试启示架构特点测试关注点渲染和逻辑分离setData的数据量和频率需要关注基于 WebView 渲染iOS 和 Android 可能出现渲染差异Native 桥通信频繁调用原生 API 时注意性能独立 JS 运行环境不支持window/document等浏览器 API1.2 小程序的生命周期小程序的启动和页面切换遵循严格的生命周期小程序级别App页面级别Page页面栈机制小程序维护了一个页面栈最多10 层。navigateTo将新页面压入栈栈深度1navigateBack从栈顶弹出当前页面栈深度-1redirectTo用新页面替换当前页面栈深度不变reLaunch清空整个页面栈栈深度重置为1switchTab关闭所有非 Tab 页面切换到 Tab 页面测试点场景操作预期结果栈溢出连续 navigaTo 10次后再跳转第11次跳转失败需用 redirectTo 或给出提示Tab切换后返回switchTab 后按返回行为由页面栈深度决定页面栈恢复小程序后台切前台页面栈保持不变页面销毁redirectTo 跳转后返回旧页面旧页面已销毁需要重新加载1.3 小程序的技术限制限制项具体数值测试方式主包体积≤ 2MB开发者工具 → 详情 → 代码包体积单个分包≤ 2MB同上所有分包总和≤ 20MB同上页面栈深度≤ 10层手动跳转验证本地缓存上限10MBwx.setStorage循环写入request 并发数10个同时发起11个请求验证单个 request 超时默认60秒可在timeout参数配置WebSocket 连接数最多2个创建第3个连接验证文件下载最大200MB下载超过200MB的文件二、功能测试每个组件拆开来看2.1 导航与页面跳转四种跳转方式的完整测试矩阵编号跳转方式测试场景操作步骤预期结果NV-01navigateTo基础跳转A页 → navigaTo B页B页打开A页在栈中保留NV-02navigateTo栈满跳转连续10次 navigaTo第11次失败提示无法跳转NV-03navigateTo带参跳转A→BURL带?id123B页onLoad(options)拿到options.id123NV-04navigateTo特殊字符参数URL参数含中文/emoji参数正确编码B页正常解码NV-05navigateBack基础返回B页 → navigaBack回到A页B页 onUnload触发NV-06navigateBack多级返回C页 → navigaBack({delta:2})直接回到A页B和C页都onUnloadNV-07redirectTo基础重定向A→redirectTo BA页 onUnload触发栈中只有B无法返回ANV-08switchTabTab页跳转从详情页 switchTab 到首页Tab所有非Tab页被关闭NV-09reLaunch基础重启从任意页 reLaunch 到首页所有页面栈清空无法返回NV-10组合各种跳转混合navigaTo→redirectTo→switchTab每一步栈深度和剩余页面符合预期2.2 用户授权体系小程序使用“使用时授权”机制不是安装时一次性弹出所有权限。授权触发时机权限类型触发API调用时需要wx.authorize需要openSetting用户信息头像昵称wx.getUserProfile否否手机号button open-typegetPhoneNumber否否地理位置wx.getLocation是是相册选择图片wx.chooseImage否每次弹—相机wx.chooseImage({sourceType:[camera]})是是录音wx.startRecord是是保存到相册wx.saveImageToPhotosAlbum是是蓝牙wx.openBluetoothAdapter是是消息订阅wx.requestSubscribeMessage否否完整授权测试用例编号场景前置条件操作步骤预期结果AU-01首次授权-允许首次启动小程序触发定位 → 弹窗点允许获取位置成功AU-02首次授权-拒绝首次启动小程序触发定位 → 弹窗点拒绝获取失败提示引导设置AU-03二次触发-已允许上次已点允许再次触发定位不弹窗直接获取位置AU-04二次触发-已拒绝上次点拒绝再次触发定位不弹窗直接失败提示引导AU-05手动关闭权限设置中关闭定位再次触发定位失败提示引导去设置开启AU-06手动开启权限设置中开启定位再次触发定位不弹窗直接获取位置AU-07拒绝后引导设置已拒绝过点去设置→ 跳转设置页正确打开wx.openSettingAU-08权限降级处理所有权限被拒绝使用需要权限的功能不闪退展示降级提示AU-09多权限连续弹窗触发多个权限先后弹窗不冲突一个接一个弹出不重叠AU-10微信权限变更系统设置改微信权限小程序行为下次调 API 重新引导授权测试特别注意Android 和 iOS 的权限弹窗 UI 不同但小程序的 API 行为应一致用户可以在微信设置→个人信息与权限→授权管理中随时撤销授权小程序下次调 API 时行为等同于首次wx.getUserProfile每次调用均弹窗确认微信规则头像昵称必须用户主动触发2.3 表单组件小程序的表单组件行为和 HTML 标准控件不完全一致这一点在写测试用例时要格外注意。2.3.1 input 输入框配置测试点type“text”正常输入、中文输入法联想词、光标位置type“number”只允许数字、小数点行为、负号支持type“idcard”身份证键盘布局、X字母输入type“digit”带小数点的数字键盘type“password”密码小眼睛切换明文密文、自动切换回密码模式password 属性输入时显示字符后隐藏不是input的type“password”maxlength边界值-1、1中文算1个长度placeholder低版本 Android 的样式差异偏上偏下confirm-type键盘右下角按钮文案done/go/search/next/send关键兼容性问题Android 部分机型 input 小尺寸时 placeholder 文字被截断iOS 的typenumber键盘没有小数点typedigit才有2.3.2 textarea 多行输入测试场景预期输入超长文本2000字正确显示滚动查看换行操作换行符正确存储键盘遮挡输入区域自动上移自动增高文字超出后自动扩展高度和底部固定按钮的交互键盘弹出时不遮挡按钮2.3.3 picker 选择器picker类型测试要点普通选择器选项展示、默认选中、选中回调、选项动态更新日期选择器min/max范围、月份天数校验2月和闰年、时间精度地区选择器省份→城市→区县三级联动多列选择器每一列的关联更新如选车型→选排量2.3.4 switch / slider / radio / checkbox组件特殊测试点switch快速连续点击不抖动、颜色自定义、disabled 状态slider滑动到 min/max 边界值、步长step验证、滑动中数值回调radio默认选中、切换选中、动态新增选项后checked状态checkbox全选/反选联动、部分选中的中间态2.4 数据缓存 Storage小程序提供了同步和异步两套 Storage API// 同步会阻塞wx.setStorageSync(key,value);constvaluewx.getStorageSync(key);wx.removeStorageSync(key);wx.clearStorageSync();// 异步不阻塞推荐wx.setStorage({key:key,data:value,success:(){}});wx.getStorage({key:key,success:(res){console.log(res.data)}});测试用例编号场景操作预期ST-01基础存取setStorage → getStorage取出正确值ST-02覆盖写入setStorage(‘a’,1) → setStorage(‘a’,2) → getStorage(‘a’)取出2ST-03移除setStorage → removeStorage → getStorage取不到ST-04清空全部setStorage N个 → clearStorage → getStorage全部全空ST-05容量上限循环 setStorage 到10MB超过上限后写入失败ST-06缓存持久化setStorage → 杀微信进程 → 重开 → getStorage仍然取到ST-07缓存隔离小程序A存的数据 → 小程序B读读不到ST-08用户切换用户A登录存数据 → 退出换用户B → 读A的数据根据产品设计保留或清空ST-09版本升级旧版小程序存数据 → 更新到新版 → getStorage数据保留ST-10数据类型存字符串/数字/对象/数组/二进制 → 取出类型和值一致ST-11并发读写同时异步写和读同一个key最终一致不报错ST-12undefined/NaN存 undefined → getStoragenull小程序内部转换2.5 支付流程每个分支的验证支付结果订单状态页面表现二次操作支付成功已支付跳转成功页不会重复扣款用户取消待支付留在当前页可重新付款支付失败待支付提示失败原因可重新付款网络中断查询后端支付状态不明状态先查再提示若已扣款不再发起支付三、兼容性测试想教育普通APP多了一个维度3.1 三轴兼容矩阵普通APP只需要考虑系统版本 手机品牌小程序还要加上微信版本 基础库版本兼容维度范围最低要求微信版本最新版 次新版 往前1-2个大版本覆盖95%用户基础库版本当前最新 上一个稳定版跟微信版本关联iOS15 / 16 / 17 / 18覆盖98% iOS用户Android10 / 11 / 12 / 13 / 14 / 15覆盖95%用户手机品牌华为/小米/OPPO/vivo/三星 × 高中低端每个品牌至少一款屏幕尺寸4.7寸 ~ 6.9寸 折叠屏各种主流尺寸3.2 基础库版本对 API 的影响微信的基础库不断更新新 API 在旧基础库上不可用。开发文档中每个 API 都标注了最低基础库版本要求。测试方法在开发者工具的**详情→本地设置**中调试基础库版本切换不同版本验证使用wx.canIUse做 API 降级判断// 检测某个API是否可用if(wx.canIUse(getLocation)){wx.getLocation({type:gcj02});}else{wx.showToast({title:当前微信版本过低请升级后使用});}常见的兼容性差异API/功能基础库要求测试注意wx.chooseAddress≥ 1.1.0低版本不可用wx.getUserInfo≥ 1.0.0新版已废弃改用button open-typegetUserInfo自定义 tabBar≥ 2.5.0基础库不够则降级为原生tabBarcover-view≥ 1.4.0旧版不支持覆盖在原生组件上wx.openSetting≥ 1.1.0旧版本调不了设置页3.3 iOS 和 Android 的渲染差异双端 WebView 内核不同同样的 WXSS 样式显示效果可能不同常见差异iOS表现Android表现解决方案input placeholder 颜色较弱较深用placeholder-style显式指定fixed 定位跟随键盘上推不跟随/行为不一致键盘弹出时改用absoluteborder-radius正常部分机型溢出不裁剪加overflow:hidden滚动回弹有弹性效果无差异不修复字体渲染偏细偏粗使用font-weight: normal避免极端半透明遮罩使用 rgba同两表现一致3.4 实际手机测试 checklist每台手机至少走一遍完整流程1. 搜索进入小程序搜索是否能搜到 2.扫码进入小程序扫小程序码 3. 首次启动 → 全部授权弹窗 → 点允许 4.首次启动 → 全部授权弹窗 → 点拒绝 → 验证降级 5. 核心业务流程全链路登录→浏览→下单→支付[测试环境]→返回 6.切换到后台再切回前台 7. 微信杀掉再重新打开小程序 8. 清理微信缓存后重新打开 9. 微信切换账号后重新打开 10. 在不同网络环境WiFi/4G/飞行模式切换下使用四、性能测试包大小 运行时4.1 包体积优化与检测为什么要关注超过2MB的主包小程序根本无法上传。包体积还直接影响启动速度——每增加100KB启动时间大约增加200ms。检测方法微信开发者工具 → 详情 → 本地代码 → 代码包体积或使用代码依赖分析工具查看哪些文件最大体积排行榜从大到小文件类型占比优化方式图片资源40-60%压缩到150KB以下大图放CDN按需加载第三方 JS 库20-30%按需引入去掉未使用的模块业务 JS 代码15-25%代码压缩、tree shakingWXML/WXSS5-10%删除无用样式、合并同类样式分包策略// app.json{pages:[pages/index/index,// 首页放主包pages/mine/mine],subPackages:[{root:packageA,// 功能模块分包pages:[pages/detail/detail,pages/order/order]}],preloadRule:{// 预加载规则pages/index/index:{network:all,packages:[packageA]// 进入首页后预加载分包}}}测试验证主包体积 ≤ 2MB分包体积 ≤ 2MB分包总和 ≤ 20MB分包加载是否流畅进入分包页面时加载时间 500ms预加载的分包是否确实在后台提前下载了4.2 启动性能测试工具微信开发者工具 → 调试器 → Audits → 体验评分指标合格优秀测量方法首屏时间 3秒 1.5秒Audits面板白屏时间 2秒 1秒开发者工具 timeline可交互时间 5秒 3秒手动计时总代码包 1.5MB 1MB详情-代码包体积首屏网络请求 5个 3个Network 面板冷启动和热启动的区别类型定义测试注意冷启动小程序被销毁后首次打开完整走 onLaunch→onLoad热启动小程序在后台切到前台只走 onShow不重新初始化测试时要分别记录冷启动和热启动的时间优化重点在冷启动。4.3 运行时性能三大性能杀手① setData 滥用setData是从逻辑层向渲染层传输数据的唯一方式每次调用都有开销。// 差每次只传一个字段多次调用this.setData({name:test});this.setData({age:18});this.setData({city:上海});// 好合并到一次 setDatathis.setData({name:test,age:18,city:上海});测试方法Audits面板 → setData 耗时排行 → 找出单次超 50ms 的调用。② 页面切换后未释放内存// 差全局变量持有了某个页面引用App.globalData.somePageThisthis;// 好页面 onUnload 时主动清理onUnload(){this.timerclearInterval(this.timer);this.data.list[];// 释放大数组}测试方法反复进入和退出页面各10次以上查看内存曲线是否只升不降。③ 过大的图片列表的缩略图使用压缩后的版本不要用原图使用lazy-load属性懒加载图片图片放在 CDN 上而非小程序代码包里4.4 体验评分工具微信开发者工具提供了完整的 Audits 面板评分报告包含检测项影响包体积直接影响下载和启动setData频率单次 50ms 影响滑动流畅度setData数据量单次 256KB 影响通信效率图片资源未压缩图片拖慢加载网络请求首屏请求数过多延长白屏时间页面切换onHide/onUnload 未清理资源WXS脚本复杂计算应放到 WXS渲染层而非 JS逻辑层五、安全测试5.1 数据传输安全小程序强制要求所有网络请求必须走 HTTPS——这是微信的硬性规定开发阶段可以通过开发者工具关闭域名校验但上线必须 HTTPS。检测项测试方法全站 HTTPS抓包查看所有请求是否都是 HTTPS证书有效性检查证书是否过期、是否自签名证书域名检查是否匹配后端域名HTTP降级尝试在代码中修改为 HTTP验证小程序是否拦截5.2 用户数据安全检测项要求测试方法openid不可暴露在前端JS或URL中全局搜索代码中是否有 openidsession_key必须只存在后端前端代码搜索session_key手机号加密传输明文不可见抓包查看手机号接口Token存储存在 Storage 中检查 Storage 中 Token 是否明文日志脱敏console不打印手机号/密码全局查 console.log 参数5.3 代码反编译与防护小程序代码包可以被解包方法是通过 root 手机进入/data/data/com.tencent.mm/MicroMsg/.../appbrand/pkg/找到 wxapkg 文件然后用工具解包。防护策略核心业务逻辑、算法、密钥放在后端前端只做展示和简单交互后端接口做完整的参数校验——不能假设前端已经验证过了敏感配置APP_SECRET、支付密钥绝对不出现在前端代码中5.4 越权与注入好Web 测试一样小程序也需要覆盖检测项测试方法横向越权修改请求参数中 userId/orderId 为其他用户的值纵向越权普通用户访问管理端接口SQL注入输入框输入 OR 11 --XSS输入框输入scriptalert(1)/script看展示页面是否执行参数篡改修改请求中金额、数量、权限等参数六、自动化测试6.1 minium微信官方测试框架minium 是微信官方推出的小程序自动化测试框架基于 Python。安装pipinstallminium基础用法importminiumclassLoginTest(minium.MiniTest):deftest_login(self):测试登录流程# 获取元素phone_inputself.page.get_element(input.phone-input)code_btnself.page.get_element(.get-code-btn)# 输入手机号phone_input.input(13800138000)# 点击获取验证码code_btn.click()# 等待验证码发送self.page.wait_for(2)# 断言toast提示self.assertText(验证码已发送)# 截图留存self.page.capture(login_step1.png)deftest_empty_phone(self):测试空手机号btnself.page.get_element(.login-btn)btn.click()# 断言错误提示toastself.page.get_element(.wx-toast)self.assertEqual(toast.text,请输入手机号)minium 支持的测试能力功能说明元素定位CSS选择器/XPath/内部ID真机调试支持扫码连接真实手机模拟操作点击/滑动/长按/输入截图任意步骤截图存档执行JS在页面中执行自定义JSMock网络请求拦截和 Mock 返回数据驱动支持参数化测试6.2 Airtest更简单的小程序自动化Airtest 是网易开源的UI自动化框架通过图像识别定位元素上手门槛更低。fromairtest.core.apiimport*# 连接设备connect_device(Android://127.0.0.1:5037/设备序列号)# 图像识别点击touch(Template(获取验证码按钮.png))# 等待元素出现wait(Template(登录成功.png),timeout10)# 文字输入text(13800138000)# 断言assert_exists(Template(登录成功.png),登录失败)6.3 微信云测服务微信官方也提供了云测平台上传小程序代码后平台自动在不同型号的真机上运行测试。适合兼容性测试的场景。七、常见问题与解决方案速查问题现象可能原因解决方案小程序白屏主包过大 / JS 执行错误检查体积 看 vConsole 报错页面滑动卡顿setData 太频繁合并 setData用 WXS 处理复杂计算图片加载慢图片太大或CDN慢压缩图片 使用 CDN 加速 lazy-load输入框光标错位Android WebView 兼容问题升级微信版本 调整 CSS真机样式和模拟器不同iOS/Android WebView 差异多真机测试 修复平台差异样式授权后仍获取不到权限系统级权限关闭引导用户去系统设置开启Storage 突然被清空微信清理缓存关键数据同步到后端页面栈溢出navigaTo 超过10次用 redirectTo 或在第10次给出提示八、小程序测试检查清单功能测试 四种跳转方式的栈行为验证 授权: 首次允许/拒绝/二次触发/手动改权限 表单: input/textarea/picker/switch/slider Storage: 存取/上限/持久化/隔离/升级 支付: 成功/取消/失败/余额不足/断网/重复支付 兼容性测试 iOS 15-18 Android 10-15 华为/小米/OPPO/vivo 至少各一款真机 微信版本: 最新版 次新版 基础库版本: 高低版本切换 折叠屏展开/折叠 平板横屏 性能测试 主包 ≤ 2MB / 总分包 ≤ 20MB 冷启动 3秒 Audits 体验评分 ≥ 80 setData 无单次超 50ms 调用 反复进退页面内存不持续增长 安全测试 全站 HTTPS / 证书有效 openid/session_key 不暴露前端 越权: 横向 纵向 注入: SQL/XSS 自动化测试 minium 或 Airtest 覆盖核心流程 失败自动截图