- 微信小程序UI自动化调研&minium的环境搭建和最佳实践
一、UI自动化背景1.1、UI自动化测试介绍UI自动化测试是一种基于用户界面的自动化测试技术,它通过模拟用户操作来测试软件的界面功能是否正常。以代码方式实现自动操作和验证的一种自动化测试手段。 与传统的单元测试和接口测试不同,UI自动化测试更关注用户实际使用软件的体验。 UI自动化,按照平台分类,主要分为Web端和App端。 Web:以Selenium驱动WebUI的自动化测试为主流 App:以Appium、Airtest等驱动App的自动化测试为主流 关于小程序的自动化测试,区别于常规的平台。 1.2、UI自动化测试的时机[图片] 按照测试金字塔的模型来看,对于不同层面的测试,需要不同形态的测试方法来保证其质量。 当我们的项目处于以下情况下的时候,UI自动化测试就显得尤为重要: 需求相对稳定重复任务较多项目开发周期长二、UI自动化测试方案选型1.1、微信小程序架构[图片] 小程序分为Android、iOS、开发者工具(调试平台)三个平台。自下而上,分为渲染层(Render)、逻辑层(Logic)、视图层(View)。微信针对对于不同平台,采用了不同渲染机制和逻辑处理机制,生成统一的视图(WXML+WXSS)。 微信追求高度统一的跨平台体验,所以给UI自动化统一的测试方案提供了必要的前提。 同时由于平台的差异,也会在不同平台存在一定差异。所以UI自动化测试,多平台真机测试也显得格外重要。 1.2、微信小程序自动化技术选型由于小程序生态方面的原因,小程序的UI自动化的自动化框架选择较少。目前有Appium、Airtest、Minium三大主流框架。 1.2.1、AppiumAppium是一个开源工具,用于自动化测试iOS手机、Android手机和Windows桌面平台上的原生、移动 Web和混合应用。它使用了各系统自带的自动化框架,无需SDK集成,Appium把这些系统本身提供的框架包装进一套API->WebDriver API中,可以使用任何语言编写Client脚本向服务器发送适当的HTTP请求。这让不同技术栈的人员都能快速上手编写测试用例。但是Appium对小程序支持的不太好,元素定位准确度还处于较低水平。 1.2.2、AirtestAirtest Project是由网易游戏推出的一款自动化测试平台,除了支持通过系统自带的自动化测试框架(POCO),还支持了通过图像识别的方式,对于非基于原生UI系统的一些游戏引擎提供了SDK的支持。其上手难度稍低,可以一定程度上通过IDE进行相关操作来生成简单的脚本指令。Airtest虽然基于图像进行控件识别,为跨端提供了一定的可能性,然而图像识别并不能达到人眼识别的准确度,页面元素的展示规则和样式受屏幕分辨率影响较大,单纯依靠图像识别来进行元素查找成功率不高,无法保证测试的准确性。 2.2.3、Minium(MiniTest)Minium是腾讯微信官方提供的自动化测试的框架,但是 minium 的功能不止于仅仅是 UI 自动化, 甚至可以使用 minium 来进行函数的 mock, 可以直接跳转到小程序某个页面并设置页面数据, 做针对性的全面测试, 这些都得益于腾讯开放了部分小程序 API 的能力。 支持一套脚本,iOS & Android & 模拟器,三端运行提供丰富的页面跳转方式,看不到也能去得到提供丰富的元素定位方式。可以获取和设置小程序页面数据,让测试不止点点点可以直接触发小程序元素绑定事件支持往 AppSerive 注入代码片段执行可以调用部分 wx 对象上的接口支持 Mock wx 对象上的接口支持 Hook wx 对象上的接口通过 suite 方式管理用例,config 管理运行设备etc...2.2.4、对比总结对于小程序自动化测试来说,Appium和Airtest为三方的自动化框架,没有微信官方的支持,所以无法深入小程序逻辑层,只能作用于渲染层,从另外一个角度来说,这两个框架还属于黑盒自动化测试的范畴。 但是Minium为微信官方支持,且可以深入到微信Api内部做相关测试。这意味着Minium不仅可以作用于渲染层,还可以作用于逻辑层。这样为自动化测试提供了非常全面的功能性测试范围。 minium的支持情况/方案: 脚本语言:python、JavaScript是否开源:是平台支持:ios真机、Android真机、开发者工具模拟器多设备运行:支持上手难度:容易,基于unittest衍生minitest,上手容易会用例即可稳定性:高测试计划:支持按照suite.json配置按需执行caseCI持续集成:支持试图检索:1.基于wxml的控件识别技术2.基于小程序底层基础库提供原生能力元素定位: 1.图像识别❌ 2.类选择器定位✅ 3.id选择器定位✅ 4.标签选择器定位✅ 5.子元素选择器定位✅ 6.后代选择器定位✅ 7.跨自定义组件的后代选择器定位✅ 8.多选择器的并集定位✅ 9.xpath定位✅ 元素定位纠错:支持hook、mock、网络拦截、微信原生native、小程序内嵌h5支持三、minium框架的介绍和支持情况以下为minium的一些核心能力。更多详细的能力可以查看官方的文档: 官方文档:https://minitest.weixin.qq.com/#/minium/Python/readme 3.1、元素定位能力minium的元素定位极其丰富,可以通过多重选择器来定位。同时也可以根据文本、xpath等常规方法来定位。 当max_timeout != 0且没有找到目标元素时, 框架尝试通过整个页面元素【推测】你可以想要查找的元素,如果有符合条件的【可能的元素】,则返回该元素实例;一般可以解决:xpath 丢失中间节点、跨自定义组件 css selector 写法不当问题; minium v.5.5支持 3.2、多账号运行能力minium支持多账号运行 [图片] 3.3、Minitest支持能力MiniTest是minium中继承自unittest.TestCase的测试基类, 可以在testcase中使用框架实例化好的Minium/App/Native实例。 也可以使用unittest中的各种断言函数 名称 类型 默认值 说明 mini minium.Minium None Minium实例,可直接调用minium.Minium中的方法 app minium.App None App实例,可直接调用minium.App中的方法 page minium.Page None 当前页面Page实例,可直接调用minium.Page中的方法 native minium.Native None Native实例,可直接调用minium.Native中的方法 logger Logger None 可以调用logger.info、logger.warning、logger.error、logger.debug打印日志, 日志内容会在报告日志中体现 test_config minium.MiniConfig None case运行时对应的配置实例, case setUp时创建 每个对象都提供了极其丰富的api支持UI自动化的操作。 3.4、断言能力minium提供了丰富的断言方法 assertFalse(expr) assertTrue(expr) assertRaises(expected_exception) assertEqual(a, b) assertNotEqual(a, b) assertAlmostEqual(a, b, places=7) assertNotAlmostEqual(a, b, places=7) assertSequenceEqual(seq1, seq2) assertListEqual(list1, list2) / assertTupleEqual(tuple1, tuple2) assertSetEqual(set1, set2) assertIn(a, b) assertNotIn(a, b) assertIs(a, b) assertIsNot(a, b) assertDictEqual(d1, d2) assertDictContainsSubset(d1, d2) assertMultiLineEqual(s1, s2) assertLess(a, b) assertLessEqual(a, b) assertGreater(a, b) assertGreaterEqual(a, b) assertIsNone(a) assertIsNotNone(a, b) assertIsInstance(obj, cls) assertNotIsInstance(a, b) assertRegex(text, expected_regex) assertNotRegex(text, unexpected_regex) assertSetContainsSubset(subset, superset) 3.5、Mock/Hook能力minium中基于mock/hook能力实现了很多实用api, mock/hook能力是否正常也关系着这一类的api能力是否能正常使用.。 Mockmock, 替换接口实现. 如wx.getStorageSync("test")返回结果是1, mock该接口后可以让其返回2 Hookhook, 在api调用前后进行插桩监控。分为: before: 函数调用前after: 函数调用后.callback: 函数回调时3.6、网络能力minium的网络记录能力,本质上是根据其hook能力来实现的。 网络请求日志文件存放在{self.test_config.case_output}/request.log中,case运行过程中所有网络日志会在case运行完毕后存储到request.log中 3.7、原生能力minium提供了Native类,实现了针对小程序内涉及原生控件(授权弹窗、弹窗、地图、分享小程序等)的操作封装。可以控制操作类型的原生操作。 [图片] 3.8、真机测试能力支持在真机上(无需配置adb等环境,直接真机运行UI自动化) [图片] 3.9、生成测试报告能力每条用例的测试结果会存放到一个目录里面,里面包含: 包含用例执行信息的json文件 用例运行中的截图 用例运行中的日志 小程序运行中的日志 基于这些数据可以生成测试报告,也可以做一些存档的事情。 [图片] 四、minium框架集成和使用4.1、注册开发者账号在微信公众平台注册小程序:https://mp.weixin.qq.com/ 注册成功后,会得到一个AppId 如果项目已有AppId,则申请添加体验者,授权即可。无需申请。 4.2、配置环境Python 3.8及以上微信 >= 7.0.7 (确认微信公共库版本 >= 2.7.3即可)微信开发者工具4.3、下载微信开发者工具下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 打开安全模式:设置 -> 安全设置 -> 服务端口:打开 4.4、拉取源码并登录开发者工具因为minium依赖于源代码的运行。 拉取源代码采用授权微信账号登录微信开发者工具。自动编译4.5、开启端口监听"path/to/cli" auto --project "path/to/project" --auto-port 9420 "path/to/cli":表示微信开发者工具的cli命令地址 "path/to/project":表示项目地址 # Mac中cli地址是固定的,如下: /Applications/wechatwebdevtools.app/Contents/MacOS/cli # Windows中,Cli地址为安装目录 windows: C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat 出现以下提示,则证明端口监听开启成功。 [图片] 4.6、创建Python工程这里采用pipenv管理,也可以直接采用pip管理 安装 pipenv 首先需要安装 pipenv,可以使用 pip 进行安装: pip install pipenv 创建项目环境 在项目目录下,使用 pipenv 创建一个新的虚拟环境并安装依赖,这会创建一个虚拟环境并生成 Pipfile 和 Pipfile.lock 文件 pipenv install 安装依赖包 使用 pipenv 安装新包: # minium依赖库 pipenv install minium # 如果需要ios真机测试, 会额外安装一些依赖库 pipenv install "minium[ios]" 环境检查 minitest -v 五、项目框架搭建5.1、直接运行测试用例这是一个城市选择的UI自动化用例代码: @minium.ddt_class() class TestDemoLocation(minium.MiniTest): tag = "TestDemoLocation:" # 首页路由 page_main_route = "/pages/index/index" # 城市选择页路由 page_location_route = "/pages/city/city" @classmethod def setUpClass(cls): super(TestDemoLocation, cls).setUpClass() @minium.ddt_case("上海", "北京") def test_location_search_city(self, city_value): """ case介绍: 1、点击首页城市定位按钮 2、跳转到城市选择页面 3、并搜索城市 4、选中搜索结果 5、返回首页,断言切换定位成功 """ sleep(1) # 点击跳转到城市选择页面 self.app.get_current_page().get_element(selector="header >>> .city-name").tap() # 等待页面跳转成功 self.app.wait_for_page(page_path=self.page_location_route, max_timeout=10) # 等待1秒,用于展示页面(不等待也可以,这里只是为了效果,否则速度过快) sleep(1) # 输入城市数据 self.app.get_current_page().get_element(selector="input", auto_fix=True).input(city_value, False) # 等待一秒展示出结果 sleep(1) # 获取结果列表 res_city_list = self.app.get_current_page().get_elements(selector=".result-city-filter-item-li", auto_fix=True) if len(res_city_list) > 0: self.logger.info(self.tag + "找到匹配城市") res_city = res_city_list[0] res_city.tap() else: self.logger.info(self.tag + "没有匹配的城市") # 等待首页跳转完成 self.app.wait_for_page(page_path=self.page_main_route, max_timeout=10) self.assertEqual(first=self.app.get_current_page().get_element(selector="header >>> .city-name").text, second=city_value, msg="城市切换成功") 六、云测本项目支持云测。建议在调试阶段通过ide来测试(本地真机速度较慢),真机测试直接使用云测。 云测的具体步骤如下: 5.1、打包项目代码上传云测平台将脚本文件上传云测平台(可编写一键打包并上传代码)。 5.2、云测平台创建测试计划代码上传完成后,可以在云测后台创建测试计划。 云测地址:https://minitest.weixin.qq.com/cloudtest/ 需要使用具备小程序权限的微信扫码登录。 创建测试计划[图片] 勾选需要云测的测试用例 [图片] 创建成功5.3、创建测试任务选择minium类型 选择刚才创建的测试计划。 若有授权弹窗场景,勾选启用小程序自动授权 勾选完成后,等待测试结果即可。 云测真机执行流程图: [图片] 环境初始化和结果处理需要 额外耗时10-15分钟,所以一般情况下会比最长测试时间要长。 环境初始化和结果处理时长不计入用户使用耗时,不会扣除用户时长 账号被占用: 测试账号不能同时运行同一个小程序上。所以当运行账号被占用时,系统会自动排队等待真机排队:云测服务底层采用WeTest真机执行,当真机被占用时,需要排队等待执行出现异常:由于真机测试,无法100%保证成功。当测试任务遇到真机断连等异常情况时,默认会自动重试一次。如果第一次执行异常导致重试的任务,测试时间会增加注意: 测试时长最短为10分钟(不超过10分钟的按照10分钟算),双平台测试,时长会加倍。 每周的免费测试时长为150分钟,超出去后需要付费。务必合理安排使用。 5.4、查看测试结果测试完成后,可查看测试结果 包括测试截图、测试日志、网络请求、性能消耗、资源占用等。均有完整的测试结果 5.5、发送测试结果(邮箱/手机)我的信息-绑定邮箱/手机 跑测完自动发送结果:(报告仅一个月有效期)
01-08 - 因为腾讯帮小忙没有小程序版,我一个人业余时间开启了帮小忙小程序开发之旅,目前已上线80个工具。
一、源起 我一直对各种新奇的小工具情有独钟,就像发现宝藏一样,每次使用都觉得乐趣无穷。2024年11月1号,我发现腾讯帮小忙网站(https://tool.browser.qq.com/)的时候,感觉发现了新大陆,搜了一下没小程序,屁颠屁颠加入官方QQ群,问小程序版呢?官方答复:木有哦! [图片] (腾讯帮小忙网站) 好吧,那我自己撸一个吧,把这些好用的工具都集合,搞个帮小忙工具箱小程序,随时随地能用,并且高性能,优化好用户体验,开干! 二、技术选型 高性能前端使用原生小程序服务端使用云开发,简单快速要好的用户体验,又是一个人,那必须搞个UI组件库,腾讯tdesign组件库目前看功能算比较丰富。代码,搞起! 三、陆续工具上线中,目前已上架80个工具(后续分享一些工具的技术实现) 文档处理工具:图片转文字、图片转 Excel、PDF 转 Excel、Word 转 PDF、PPT 转 PDF、Excel 转 PDF、各种文档转 PDF、PDF 转 Word、PDF 转 PPT、获取及修改 PDF 元数据、PDF 合并、PDF 拆分、修改 PDF 页面尺寸、图片转 PDF、PDF 转图片数据计算工具:字数计算、二维码生成与解析、数字转中文大小写、在线文件大小检测、长度转换、温度转换、BMI 计算、血型遗传计算、投资收益计算识别分类工具:营业执照识别、增值税发票识别、车型识别、菜品识别、动物识别、植物识别、九宫格切图、人像智能抠图、商品智能抠图、通用智能抠图文本处理工具:文字转拼音、简体繁体字互转、中文火星文互转、中文笔画顺序库、汉字偏旁知识娱乐工具:成语大全、歇后语、组词大师、各国首都、车牌归属地、电话区号查询、IP 归属地查询、大学四六级、考研历年真题、看图猜成语、生成随机数、生成随机密码、花语大全、助睡眠动图、常用电话大全、亲戚关系计算器图像处理工具:图片压缩、图片编辑、图片格式转换、图片黑白化开发辅助工具:base64 编码、uuid 生成、yaml/json 互相转换、md5 加密、字节数换算、url 编解码、URL 解析、进制转换、时间戳转换、开发语言输出 hello world、制作 ico 图标其他杂项工具:闪光灯、明星脸、制作证件照、取名字、文本颜艺、颜色转换 四、部分页面图 [图片][图片] [图片][图片] 五、未来展望 短期目标先上到100个工具,然后重构整个代码,现在每个工具箱都是一个页面,不方便维护。
2024-12-31 - 出现“无法确认该网页的安全性,请谨慎访问”的解决方法。
对于外部链接这一块审核机制是非常严格的,甚至是出现了相关的词汇,包括相关的二级域名内容都有可能被列入“无法确认该网页的安全性,请谨慎访问”甚至可能出现“经网址安全检测,该网页包含不安全内容。为维护绿色上网环境,已停止访问。”出现这一情况该怎么处理? 完成ICP备案,如无备案则先补充备案 第一步 根据规范自查《微信外部链接内容管理规范》http://weixin.qq.com/cgi-bin/readtemplate?t=weixin_external_links_content_management_specification 确认没有违反上述内容的再进行下一步,如有则先整改。 第二步 点击页面上的“申请恢复访问”,提交相关资料发起申请。等待即可,若一段时间/长时间没有反馈,则再向相关的人员进行反馈。 第三步,其他方法 注意目前在社区中可以在同类问答帖子中找到下图中这个官方人员,也可以点击下方链接咨询,但目前社区整体反馈量较大,运营人员可能处理不过来,也可以寻找在线客服进行咨询解决。 [图片] https://developers.weixin.qq.com/community/personal/oCJUsw7Xa-CSZJqDD0A33SVPHcqY 具体反馈的需要提供资料(域名、备案截图、SSL检测报告)并邀请相关人员回答等待即可 若域名被封禁,可通过邮件(moment@tencent.com)提交解封申请,附备案号、域名证书及情况说明 出现问题优先自查!
05-07 - Webview、Skyline 混用切换耗时吗?
在学习 Skyline 的过程中,许多开发者会有一个疑问:是否可以将小程序的部分页面迁移到 Skyline? 对 Skyline 感兴趣但还没有完全决定是否要使用的开发者来说,可能只想先尝试一下 Skyline 的功能。 实际上,Skyline 支持最小粒度的页面配置,意味着我们可以为某个页面单独开启 Skyline,而不必将整个小程序迁移到 Skyline 上。 开发者可以更加灵活地使用 Skyline,并逐步将小程序迁移到 Skyline 上,从而获得更好的性能和用户体验。 我们知道 Webview 和 Skyline 是两个渲染引擎,对于 Webview 和 Skyline 混用,大家又有新的疑问:当进行页面切换的时,混用是否会增加耗时? 这里需要分三种情况: 1、Skyline -> Webview:这种情况取决于 app.json 里配置的全局 renderer,即小程序设置的默认渲染引擎 如果全局 renderer 是 Skyline,那么 Webview 不会被预加载,此时 Skyline 跳转 Webview 耗时会增加,开发者需要手动调用 wx.preloadWebview 做预加载。如果全局 renderer 是 Webview,由于 Webview 默认会预加载,所以 Skyline -> Webview 和 Webview -> Webview 耗时一样,不会增加耗时。2、Webview -> Skyline:Skyline 默认都不会被预加载,开发者需要手动调用 wx.preloadSkylineView 做预加载。 3、Skyline -> Skyline:速度变快,因为多个页面复用同一个 Skyline 实例。 根据上述三种情况的分析,为了保证混用渲染引擎的页面切换耗时最短,我们需要在以下时机进行预加载。 wx.preloadWebview 当 Skyline 页面跳转到 Webview 页面时并且全局 renderer 是 Skyline 由于 Skyline 不影响渲染线程,所以预加载 Webview 的时机只需要在主要逻辑完成后即可 // Skyline page.js Page({ onShow() { // 等待执行完主要逻辑后进行预加载 wx.preloadWebview() } }) wx.preloadSkylineView 当 Webview 页面跳转 Skyline 页面时,因为 Skyline 默认不预加载,所以我们需要手动预加载。 建议大家在 Skyline 页面的 onShow 生命周期里延迟一段时间后调用,这样可以保证在 Skyline 页面被返回时也能够重新预加载。 注意:预加载会影响当前页面的渲染,建议异步延迟去执行预加载操作 // Webview page.js Page({ onShow() { // 延迟 200ms 预加载 Skyline // 建议这个延迟时机在页面渲染完成之后 setTimeout(() => { wx.preloadSkylineView() }, 200) } }) 做好预加载是提高 Webview 和 Skyline 混用体验的有效方式,需要根据实际情况进行调整和优化,以达到最佳的预加载效果。
2024-03-07