跨端跨框架 UI 自动化测试方案 Flybirds

背景 多端研发对于当今时代的前端开发来说是个绕不过去的话题,为了解决这些问题,行业内推出了很多开发方案,但是跨端 UI 自动化测试的解决方案并不多。
Flybirds从2022年初开源至今已有3月有余,通过与社区内活跃用户的交流和反馈,推出了v0.2 版本的跨端跨框架测试方案,一套脚本多端运行,插件化的架构设计,也方便社区开发者自由加入扩展,一起共建成长。
v0.2 新增特性

  • 支持多端脚本复用
  • 支持多浏览器渲染引擎:Chromium、WebKit 和 Firefox
  • 支持多浏览器并发模式下的兼容性测试
我们需要一个怎么样的多端测试方案 近几年,每隔一段时间就会有很多新的开发框架出现,带来了更好的开发体验和性能的同时,也给自动化测试创造了很多难题。
我们到底需要一个怎样的多端测试方案呢?从 Flybirds 的视角来说,我们希望多端测试不会成为研发流程中的障碍,特别是多端生态整体呈现欣欣向荣之时,自动化测试方案应和开发方案共同成长。
不论是 Web 、React Native 端,还是Native端,理想的方案应该进行多端适配,保留良好扩展,兼顾更多框架,由社区共同建设,促进整体生态繁荣,因此就有了Flybirds 向社区提供的跨端跨框架测试方案。
插件化架构 跨端跨框架 UI 自动化测试方案 Flybirds
文章图片

插件化架构帮助我们将每一个端的能力拆分开, 插件提供运行时所需的组件、API 和配置,Flybirds 将它们分别注入对应的生命周期。
文件结构
├─ cli脚手架 ├─ core |├─ config_manage.py配置管理 |├─ dsl |│├─ globalization国际化处理 |│└─ stepStep 列表 |├─ global_resource.py全局配置 |├─ launch_cycle生命周期管理 |└─ plugin |├─ event事件管理 |├─ plugin_manager.py插件管理 |└─ plugins |├─ androidAndriod 相关处理 |├─ iosiOS 相关处理 |└─ webWeb 相关处理 ├─ report报告 ├─ template模板处理 └─ utils

DSL step 列表
当然在这个架构中, 各端略有不同,主要是各端的平台差异性导致,以下是各端具体支持的 DSL step 列表, 大部分step能够适用于多端
语句模板 语义 适用于
等待[]秒 等待一段时间 ALL
页面渲染完成出现元素[] 进入新的页面时检查指定元素是否渲染完成 ALL
点击[] 点击指定属性的元素 ALL
点击文案[] 点击指定文案的元素 ALL
点击屏幕位置[][] 点击屏幕指定位置 ALL
在 [] 中输入[] 在指定选择器中输入字符串 ALL
向[] 查找[]的元素 向指定方向查找指定属性的元素 ALL
全屏向[] 滑动[] 全屏向指定方向滑动指定距离 ALL
[] 向[] 滑动[] 在指定区域内向指定方向滑动指定距离 ALL
存在[]的文案 检查页面中存在指定的字符串 ALL
不存在[]的文案 检查页面中不存在指定的字符串 ALL
存在[]的元素 检查页面中存在指定属性的元素 ALL
不存在[]的元素 检查页面中不存在指定属性的元素 ALL
文案[] 的属性[] 为 [] 检查页面中指定文案的指定属性为指定值 ALL
元素[] 的属性[] 为 [] 检查页面中指定元素的指定属性为指定值 ALL
[] 的文案为[] 检查页面中指定元素的文案等于指定值 ALL
[] 的文案包含[] 检查页面中指定元素的文案包含指定值 ALL
回到首页 回到首页 ALL
全屏截图 保存当前屏幕图像 ALL
登录账号[] 密码[] 使用账号密码进行登录 ALL
退出登录 退出系统登录 ALL
结束录屏 结束录制视频 ALL
在[] 中向 [] 查找 [] 的元素 在指定 选择器 的元素内 向指定方向滑动查找 指定选择器的元素 ALL
跳转到[] 跳转到指定的url地址 Android,Web
返回上一页 返回上一页面 Android,Web
开始录屏 开始录制视频 Android,iOS
开始录屏超时[] 开始录屏并设置超时时间 Android,iOS
连接设备[] 连接测试设备 Android,iOS
启动APP[] 启动APP Android,iOS
重启APP 重启APP Android,iOS
关闭App 关闭App Android,iOS
安装APP[] 安装APP Android
删除APP[] 删除APP Android
----- ----- -----
多端应用例子 测试用例
功能: 乘机人模块@p1 @android @web 场景:外露乘机人_选择列表页乘机人 当跳转页面到[单程填写页] 那么 页面渲染完成出现元素[已选乘机人姓名] 那么 [选择乘机人文案]的文案为[选择乘机人] 那么 [已选乘机人姓名]的文案为[李易峰] 那么 [已选乘机人证件类型]的文案为[护照] 那么 [已选乘机人证件号]的文案为[YHE77] 那么 存在[乘客类型标签儿童]的元素 那么 返回上一页

页面对象管理
多端项目中的页面对象管理,是通过json文件进行统一管理,通常存在以下两种情况
  1. 各端相同时,参考以下配置
    // 元素定位配置 ele_locator.json { "选择乘机人文案": “testid=passger_check”, "已选乘机人姓名": “testid=passger_name_checked”, "已选乘机人证件类型": “testid=passger_ct_checked”, "已选乘机人证件号": “testid=passger_cn_checked” }

  2. 各端不同时,通过android、ios、web区分
    // scheme配置 schema_url.json { "单程填写页": { "android": "urlschemel://auth_activity", "ios": "urlschemel://ios_auth_activity", "web": "https://address" } }// 元素定位配置 ele_locator.json { "乘客类型标签儿童": { "android": "textid=passger_type_child", "ios": "lableid=passger_type_child", "web": "xpath=//html/body/div" } }

数据驱动参数化 实际项目中,大部分的自动化测试都是基于数据驱动参数化,因此还需要搭配「 场景大纲+例子」一起使用,这里我们对上面的例子进行改造:
功能: 乘机人模块@p1 @android @web 场景大纲:外露乘机人_选择列表页乘机人 当跳转页面到[单程填写页] 那么 页面渲染完成出现元素[已选乘机人姓名] 那么 的文案为 那么 存在[乘客类型标签儿童]的元素 那么 返回上一页例子: |element|title| |选择乘机人文案|选择乘机人| |已选乘机人姓名|李易峰| |已选乘机人证件类型|护照| |已选乘机人证件号|YHE77| </code></blockquote><br /> 多浏览器并发 依托PlayWright的跨浏览器能力,Flybirds支持所有的现代渲染引擎,包括 Chromium、WebKit 和 Firefox。<br><img alt="跨端跨框架 UI 自动化测试方案 Flybirds" onload="javascript:ImgReSize(this)" src="http://img.readke.com/220509/0Z95J226-1.jpg"/> <br /> 文章图片 <br /> <br /> Flybirds支持多浏览器并发模式,方便高效的进行浏览器兼容性测试<br /> 配置参数<br /> <blockquote><code>// browserType: 配置浏览器内核 "web_info": { "headless": true, "browserType": ["firefox","chromium","webkit"], "defaultTimeout": 30 },</code></blockquote><br /> 执行命令<br /> <blockquote><code># 可通过参数指定浏览器内核 flybirds run -D browserType=webkit,firefox,chromium</code></blockquote><br /> 运行前检查 接下来,开始运行前,请先对运行环境进行检查<br /> Android、iOS<br /> <ol> <li>请确保配置的测试设备能够正常连接<br /> <ul> <li>Android: 执行命令 <code>adb devices</code> , 检查设备列表中是否包含测试设备</li> <li>iOS:以<code>tidevice</code>库举例,执行命令 <code>tidevice list</code>,检查设备列表中是否包含测试设备</li> </ul></li> <li><strong>【跨端跨框架 UI 自动化测试方案 Flybirds】</strong>下载安装测试包<br /> <ul> <li>Android:框架会通过<code>config</code>中配置的<code>packagePath</code>自动下载测试包并安装(请确保手机已经打开”允许安装未知来源“ ),也可手动下载安装。</li> <li>iOS:<br /> <ol> <li>请手动下载演示APP进行安装</li> <li>开启wdaproxy<br /> <blockquote><code> tidevice --udid $udid wdaproxy -B $web_driver_angnt_bundle_id -p $port</code></blockquote><br /> </li> </ol></li> </ul></li> </ol> Web<br /> Web项目执行前,先检查浏览器环境是否已安装<br /> <blockquote><code># 查看支持安装的浏览器 playwright install --help# 不带参数的运行,将安装默认所有的浏览器 playwright install# 通过提供一个参数来安装特定的浏览器 playwright install webkit </code></blockquote><br /> 运行 你可以很方便的通过 cli 切换执行环境, 筛选case和控制并发数量,下面列出了一些常用命令<br /> <blockquote><code># 查看运行项目时支持的操作 flybirds run --help#执行features目录下所有的feature文件 cd {PATH_TO_PROJECT_FOLDER} flybirds run# 指定需要执行的feature集合,可以是目录,也可以指定到具体feature文件 flybirds run -P ./features/test/demo.feature# 运行有特定tag的场景,多个用逗号隔开,‘-’开头表示不运行包含此tag的场景 flybirds run -T tag1,tag2,-tag3,tag4# 切换到Web环境执行用例 flybirds run -D platform=web # 切换到Android环境执行用例 flybirds run -D platform=Android# 切换到iOS环境执行用例 flybirds run -D platform=iOS # 执行tag为android的用例 flybirds run -T android -D platform=Android # 指定并发执行时开启进程的最大数量。默认是4,只在web环境生效 flybirds run --path features -p 5 </code></blockquote><br /> 配置 以下是各端运行前必须的配置项<br /> <ul> <li>Android配置项:deviceId、packageName</li> <li>IOS配置项:platform、deviceId、packageName、webDriverAgent、</li> <li>Web配置项:platform、browserType、headless</li> </ul> <img alt="跨端跨框架 UI 自动化测试方案 Flybirds" onload="javascript:ImgReSize(this)" src="http://img.readke.com/220509/0Z95Kc2-2.jpg"/> <br /> 文章图片 <br /> <br /> 自定义框架扩展 Flybirds的插件式设计模式,保留了良好的扩展,未来我们会开放更多。<br /> 修改扩展<br /> 如果你希望在项目中修改当前扩展,你可以用本地文件替换plugin下面的(app,device,element,app,step,screen,screen_record),并在 "plugin_info.json" 中做相应配置。<br /> 比如你希望修改web中screen.py文件:<br /> <blockquote><code>1. 在本地创建一个py文件命名为 screen.py 2. 在plugin_info.json 的web中添加如下配置:</code></blockquote><br /> <blockquote><code>"screen": { "path": "{local_path}/screen.py", "ns": "screen.plugin.myextend" }</code></blockquote><br /> <blockquote> {local_path} 为本地路径,"ns"为包名,注意包名的唯一性(以上包名只是例子不做强制限制) </blockquote> 内部增强包 对于团队内部通用的自定义功能,可以考虑创建一个extend package,Flybirds支持动态加载,package命名包含“-flybirds-plugin”即可。 携程机票内部,针对DevOps的各类工具,增强包中都进行了对接,安装后就可以使用。<br /> 持续集成 cli提供的命令行执行模式,可以非常方便加入各种持续集成工具.<br /> 以Jenkins为例:<br /> <blockquote><code># Inside the jenkins shell command cd {PATH_TO_PROJECT_FOLDER} # Run flybirds run -P ./features/test/everything.feature -define platform=Android cp -R reports $WORKSPACE</code></blockquote><br /> 发版计划 我们将按照 SemVer 版本控制规范进行发版。逐步新增功能和代码优化,非常欢迎您加入到我们的共建计划中,在 GitHub 上提出您的宝贵建议,以及在使用时遇到的一切问题,我们也会对此每周进行一次小版本的迭代。您也可以在这里给我们精神支持,点上一颗 Star。<br /> 参考链接 <ul> <li>GitHub地址:https://github.com/ctripcorp/...</li> <li>PyPI地址:https://pypi.org/project/flyb...</li> <li>Pages:https://ctripcorp.github.io/f...</li> <li>PlayWright: https://github.com/microsoft/...</li> <li>Airtest: https://github.com/AirtestPro...</li> <li>Behave: https://github.com/behave/behave</li> <li>欢迎在 GitHub issues 和Discussions区提问</li> <li>支持邮箱:flybirds_support@trip.com</li> </ul></p> <div class="dede_pages"><ul></ul></div> <div class="pcd_ad"> <center><div class="_ahwullr0ac"></div> <script type="text/javascript"> (window.slotbydup = window.slotbydup || []).push({ id: "u6834461", container: "_ahwullr0ac", async: true }); </script> <script type="text/javascript" src="//cpro.baidustatic.com/cpro/ui/cm.js" async="async" defer="defer" > </script></center> </div> <div class="mbd_ad"> <div style=margin-top:10px;margin-bottom:10px;> <div class="_i7aftr79jl"></div> <script type="text/javascript"> (window.slotbydup = window.slotbydup || []).push({ id: "u5950612", container: "_i7aftr79jl", async: true }); </script> <!-- ½űֻһ --> <script type="text/javascript" src="//cpro.baidustatic.com/cpro/ui/cm.js" async="async" defer="defer" > </script> </div> </div> <h3>推荐阅读</h3> <ul class="post-loop post-loop-default cols-0"> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/2080747.html" title="英雄杀里的商鞅怎么变法"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="英雄杀里的商鞅怎么变法" src="http://img.readke.com/230514/1Q42Lc3-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/2080747.html"> <b>英雄杀里的商鞅怎么变法 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/2386562.html" title="贴与帖的有什么区别"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="贴与帖的有什么区别" src="http://img.readke.com/230602/0HF0H45-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/2386562.html"> <b>贴与帖的有什么区别 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/1333592.html" title="组装电脑配件价格表 「电脑主机配置」"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="组装电脑配件价格表 「电脑主机配置」" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/1333592.html"> <b>组装电脑配件价格表 「电脑主机配置」 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/10092NY92021.html" title="产品|8个月下跌1200元,5nm芯片+IP68防水,优质旗舰售价大跳水"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="产品|8个月下跌1200元,5nm芯片+IP68防水,优质旗舰售价大跳水" src="https://p0.ssl.img.360kuai.com/t019534874eb88bd6dc.jpg?size=629x356"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/10092NY92021.html"> <b>产品|8个月下跌1200元,5nm芯片+IP68防水,优质旗舰售价大跳水 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/012242M942022.html" title="苹果|苹果重回第一,“十三香”所言非虚,三大因素吸引国人关注"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="苹果|苹果重回第一,“十三香”所言非虚,三大因素吸引国人关注" src="https://p0.ssl.img.360kuai.com/t013e6883f4136817a4.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/012242M942022.html"> <b>苹果|苹果重回第一,“十三香”所言非虚,三大因素吸引国人关注 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3485840.html" title="前台服务员英语怎么写 服务器前台英文怎么说"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="前台服务员英语怎么写 服务器前台英文怎么说" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3485840.html"> <b>前台服务员英语怎么写 服务器前台英文怎么说 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/1145726.html" title="4d厨房黄线红线什么意思 4d厨房什么意思"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="4d厨房黄线红线什么意思 4d厨房什么意思" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/1145726.html"> <b>4d厨房黄线红线什么意思 4d厨房什么意思 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/1314589.html" title="商用全自动榨油机器价格 家用智能榨油机"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="商用全自动榨油机器价格 家用智能榨油机" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/1314589.html"> <b>商用全自动榨油机器价格 家用智能榨油机 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/2824697.html" title="海带韭菜 高血压多吃这些菜降压快"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="海带韭菜 高血压多吃这些菜降压快" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/2824697.html"> <b>海带韭菜 高血压多吃这些菜降压快 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3206941.html" title="天造地设怎么造句,天造地设成语造句"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="天造地设怎么造句,天造地设成语造句" src="http://img.readke.com/231008/0I04631b-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3206941.html"> <b>天造地设怎么造句,天造地设成语造句 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/122SZ1232021.html" title="oled|OPPO:两款新机遭曝光,两款老机型开始提前降价让路!"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="oled|OPPO:两款新机遭曝光,两款老机型开始提前降价让路!" src="https://p0.ssl.img.360kuai.com/t01e0961fecdffabdab.jpg?size=641x597"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/122SZ1232021.html"> <b>oled|OPPO:两款新机遭曝光,两款老机型开始提前降价让路! </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3676004.html" title="冄怎么读 冄字应该怎么读"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="冄怎么读 冄字应该怎么读" src="http://img.readke.com/231208/03043BX1-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3676004.html"> <b>冄怎么读 冄字应该怎么读 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/1306486.html" title="阿什顿马丁车型 「跑车图片大全大图」"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="阿什顿马丁车型 「跑车图片大全大图」" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/1306486.html"> <b>阿什顿马丁车型 「跑车图片大全大图」 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/1184306.html" title="油性皮肤一天洗几次脸最好"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="油性皮肤一天洗几次脸最好" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/1184306.html"> <b>油性皮肤一天洗几次脸最好 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3411770.html" title="电视机显示屏换排线"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="电视机显示屏换排线" src="http://img.readke.com/231111/053F91940-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3411770.html"> <b>电视机显示屏换排线 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/2499138.html" title="感情可遇不可求的意思 感情可遇而不可求是什么意思"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="感情可遇不可求的意思 感情可遇而不可求是什么意思" src="http://img.readke.com/230612/0100421037-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/2499138.html"> <b>感情可遇不可求的意思 感情可遇而不可求是什么意思 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/121235V642021.html" title="《如懿传》如懿出冷宫,这段无声胜有声的表演,你到底看懂了几点()"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="《如懿传》如懿出冷宫,这段无声胜有声的表演,你到底看懂了几点()" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/121235V642021.html"> <b>《如懿传》如懿出冷宫,这段无声胜有声的表演,你到底看懂了几点() </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3319269.html" title="结草衔环是什么意思 结草衔环的意思"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="结草衔环是什么意思 结草衔环的意思" src="http://img.readke.com/231031/0042313444-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3319269.html"> <b>结草衔环是什么意思 结草衔环的意思 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/4186702.html" title="android4.4 camera分析"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="android4.4 camera分析" src="/images/defaultpic.gif"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/4186702.html"> <b>android4.4 camera分析 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/3414383.html" title="三菱空调显示错误信息代码处理方法?三菱空调故障码怎么查"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="三菱空调显示错误信息代码处理方法?三菱空调故障码怎么查" src="http://img.readke.com/231111/101I43424-0-lp.jpg"> </a> </div> <div class="item-content"> <h4 class="item-title"> <a href="/c/3414383.html"> <b>三菱空调显示错误信息代码处理方法?三菱空调故障码怎么查 </b></a></h4> <div class="item-meta"> <div class="item-meta-right"> </div> </div> </div> </li> </ul> <p><br /><ul class="post-loop post-loop-list cols-4"><li><a href="/c/675546.html" title="图像融合|SeAFusion:首个结合高级视觉任务的图像融合框架" target="_blank">图像融合|SeAFusion:首个结合高级视觉任务的图像融合框架 </a></li> <li><a href="/c/675545.html" title="图像融合|通用图像融合框架论文及代码整理" target="_blank">图像融合|通用图像融合框架论文及代码整理 </a></li> <li><a href="/c/675446.html" title="分享自己写的基于Dapper的轻量级ORM框架~" target="_blank">分享自己写的基于Dapper的轻量级ORM框架~ </a></li> <li><a href="/c/673798.html" title="Spring使用ORM框架示例" target="_blank">Spring使用ORM框架示例 </a></li> <li><a href="/c/673503.html" title="Android 常用开源框架源码解析 系列dagger2呆哥兔 依赖注入库" target="_blank">Android 常用开源框架源码解析 系列dagger2呆哥兔 依赖注入库 </a></li> <li><a href="/c/673501.html" title="Android 常用开源框架源码解析 系列picasso 图片框架" target="_blank">Android 常用开源框架源码解析 系列picasso 图片框架 </a></li> <li><a href="/c/673500.html" title="Android 常用开源框架源码解析 系列Rxjava 异步框架" target="_blank">Android 常用开源框架源码解析 系列Rxjava 异步框架 </a></li> <li><a href="/c/673488.html" title="wappalyzer 上各种开源框架功能" target="_blank">wappalyzer 上各种开源框架功能 </a></li> <li><a href="/c/673397.html" title="盘古开发框架集成|盘古开发框架集成 ShenYu 网关实现 Dubbo 泛化调用" target="_blank">盘古开发框架集成|盘古开发框架集成 ShenYu 网关实现 Dubbo 泛化调用 </a></li> <li><a href="/c/673192.html" title="开源框架|开源框架 WebFirst 一键生成项目,在线建表" target="_blank">开源框架|开源框架 WebFirst 一键生成项目,在线建表 </a></li> </ul></p> <div class=entry-copyright> <p></p> </div> </div> <div class="entry-footer"> <div class="prev-next sb br mb clearfix"> <p class="post-prev fl ellipsis">上一篇:<a href='/c/675914.html'>node|node 异常数据响应排查(pm2 Cluster Mode、异步)</a> </p> <p class="post-next fr ellipsis">下一篇:<a href='/c/675916.html'>SpringBoot基础</a> </p> </div> </div> </div> </article> </main> <aside class="sidebar"> <div class="widget widget_post_thumb"> <h3 class="widget-title"><span>更多...</span></h3> <ul> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675916.html" title="SpringBoot基础"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="SpringBoot基础" src="http://img.readke.com/220509/09100R601-0-lp.png"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675916.html" title="SpringBoot基础">SpringBoot基础</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675915.html" title="跨端跨框架 UI 自动化测试方案 Flybirds"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="跨端跨框架 UI 自动化测试方案 Flybirds" src="http://img.readke.com/220509/0Z95GF5-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675915.html" title="跨端跨框架 UI 自动化测试方案 Flybirds">跨端跨框架 UI 自动化测试方案 Flybirds</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675914.html" title="node|node 异常数据响应排查(pm2 Cluster Mode、异步)"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="node|node 异常数据响应排查(pm2 Cluster Mode、异步)" src="http://img.readke.com/220509/0Z94W1X-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675914.html" title="node|node 异常数据响应排查(pm2 Cluster Mode、异步)">node|node 异常数据响应排查(pm2 Cluster Mode、异步)</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675887.html" title="创业创新|大厂中年人新流行:精准逃顶,下场创业"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="创业创新|大厂中年人新流行:精准逃顶,下场创业" src="http://img.readke.com/220509/0Z1105419-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675887.html" title="创业创新|大厂中年人新流行:精准逃顶,下场创业">创业创新|大厂中年人新流行:精准逃顶,下场创业</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675886.html" title="企业办公|居家办公,我被公司用摄像头“盯梢”"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="企业办公|居家办公,我被公司用摄像头“盯梢”" src="http://img.readke.com/220509/0Z05C954-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675886.html" title="企业办公|居家办公,我被公司用摄像头“盯梢”">企业办公|居家办公,我被公司用摄像头“盯梢”</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675885.html" title="汽车出行|原材料涨声一片,油电叫苦连天"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="汽车出行|原材料涨声一片,油电叫苦连天" src="http://img.readke.com/220509/0Z041G11-0-lp.png"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675885.html" title="汽车出行|原材料涨声一片,油电叫苦连天">汽车出行|原材料涨声一片,油电叫苦连天</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675884.html" title="健身|最赚钱健身博主:25岁,抖音抢下她"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="健身|最赚钱健身博主:25岁,抖音抢下她" src="http://img.readke.com/220509/0Z02V421-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675884.html" title="健身|最赚钱健身博主:25岁,抖音抢下她">健身|最赚钱健身博主:25岁,抖音抢下她</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675831.html" title="vue 移动端禁用安卓手机返回键"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="vue 移动端禁用安卓手机返回键" src="/images/defaultpic.gif"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675831.html" title="vue 移动端禁用安卓手机返回键">vue 移动端禁用安卓手机返回键</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675830.html" title="spring boot项目application.properties多环境配置文件jar包外部配置文件"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="spring boot项目application.properties多环境配置文件jar包外部配置文件" src="http://img.readke.com/220509/0TQ1L42-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675830.html" title="spring boot项目application.properties多环境配置文件jar包外部配置文件">spring boot项目application.properties多环境配置文件jar包外部配置文件</a></p> </div> </li> <li class="item"> <div class="item-img"> <a class="item-img-inner" href="/c/675829.html" title="Android app 性能优化的思考--性能卡顿不好的原因在哪()"> <img width="480" height="300" class="attachment-default size-default wp-post-image j-lazy" alt="Android app 性能优化的思考--性能卡顿不好的原因在哪()" src="http://img.readke.com/220509/0TP0K23-0-lp.jpg"> </a></div> <div class="item-content"> <p class="item-title"><a href="/c/675829.html" title="Android app 性能优化的思考--性能卡顿不好的原因在哪()">Android app 性能优化的思考--性能卡顿不好的原因在哪()</a></p> </div> </li> </ul> </div> </aside> </div> </div> <footer class="footer"> <div class="container"> <div class="clearfix"> <div class="footer-col footer-col-logo"> <!--<img src="/skin/images/logo-footer.png">--></div> <div class="footer-col footer-col-copy"> <ul class="footer-nav hidden-xs"> <li class="menu-item menu-item-706"><a href="/baike/">生活百科</a></li> <li class="menu-item menu-item-706"><a href="/it/">it技术</a></li> </ul> <div class="copyright"> <p>Copyright © 2017-2022 锐客网 <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow">京ICP备11041112号-41</a> </p> </div> </div> <div class="footer-col footer-col-sns"> <div class="footer-sns"> </div> </div> </div> </div> </footer> <div class="action action-style-0 action-color-0 action-pos-1" style="bottom:15%;"> <div class="action-item gotop j-top"> <i class="web-icon wi action-item-icon"><svg aria-hidden="true"> <use xlink:href="#wi-arrow-up-2"></use> </svg></i></div> </div> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?79e4e485d34c6fc717489eaa10b314e3"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </div> <script>var _web_js={};</script> <script src="/skin/js/index.js"></script> </body> </html>