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

发布时间:2023-04-01 16:00

背景

多端研发对于当今时代的前端开发来说是个绕不过去的话题,为了解决这些问题,行业内推出了很多开发方案,但是跨端 UI 自动化测试的解决方案并不多。

Flybirds从2022年初开源至今已有3月有余,通过与社区内活跃用户的交流和反馈,推出了v0.2 版本的跨端跨框架测试方案,一套脚本多端运行,插件化的架构设计,也方便社区开发者自由加入扩展,一起共建成长。

v0.2 新增特性

  • 支持多端脚本复用
  • 支持多浏览器渲染引擎:Chromium、WebKit 和 Firefox
  • 支持多浏览器并发模式下的兼容性测试

我们需要一个怎么样的多端测试方案

近几年,每隔一段时间就会有很多新的开发框架出现,带来了更好的开发体验和性能的同时,也给自动化测试创造了很多难题。

我们到底需要一个怎样的多端测试方案呢?从 Flybirds 的视角来说,我们希望多端测试不会成为研发流程中的障碍,特别是多端生态整体呈现欣欣向荣之时,自动化测试方案应和开发方案共同成长。

不论是 Web 、React Native 端,还是Native端,理想的方案应该进行多端适配,保留良好扩展,兼顾更多框架,由社区共同建设,促进整体生态繁荣,因此就有了Flybirds 向社区提供的跨端跨框架测试方案。

插件化架构

\"跨端跨框架

插件化架构帮助我们将每一个端的能力拆分开, 插件提供运行时所需的组件、API 和配置,Flybirds 将它们分别注入对应的生命周期。

文件结构

                                                                 
├─ cli                            脚手架
├─ core
|   ├─ config_manage.py         配置管理
|   ├─ dsl
|   │    ├─ globalization       国际化处理
|   │    └─ step                Step 列表
|   ├─ global_resource.py       全局配置
|   ├─ launch_cycle             生命周期管理
|   └─ plugin
|        ├─ event               事件管理
|        ├─ plugin_manager.py   插件管理
|        └─ plugins                    
|             ├─ android        Andriod 相关处理
|             ├─ ios            iOS 相关处理
|             └─ web            Web 相关处理
├─ 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></pre> 
 <h2>多浏览器并发</h2> 
 <p>依托PlayWright的跨浏览器能力,Flybirds支持所有的现代渲染引擎,包括 Chromium、WebKit 和 Firefox。<br><span class=\"img-wrap\"><a href=\"https://img.it610.com/image/info9/8fbd05e1cd6548afb8177f33aca13600.jpg\" target=\"_blank\"><img class=\"lazy\" alt=\"跨端跨框架 UI 自动化测试方案 Flybirds_第2张图片\" title=\"image\" src=\"https://img.it610.com/image/info9/8fbd05e1cd6548afb8177f33aca13600.jpg\" width=\"650\" height=\"130\" style=\"border:1px solid black;\"></a></span></p> 
 <p>Flybirds支持多浏览器并发模式,方便高效的进行浏览器兼容性测试</p> 
 <h3>配置参数</h3> 
 <pre><code>// browserType: 配置浏览器内核
  \"web_info\": {
    \"headless\": true,
    \"browserType\": [\"firefox\",\"chromium\",\"webkit\"],  
    \"defaultTimeout\": 30
  },</code></pre> 
 <h3>执行命令</h3> 
 <pre><code class=\"bash\"># 可通过参数指定浏览器内核
flybirds run -D browserType=webkit,firefox,chromium</code></pre> 
 <h2>运行前检查</h2> 
 <p>接下来,开始运行前,请先对运行环境进行检查</p> 
 <h3>Android、iOS</h3> 
 <ol> 
  <li><p>请确保配置的测试设备能够正常连接</p> 
   <ul> 
    <li>Android: 执行命令 <code>adb devices</code> , 检查设备列表中是否包含测试设备</li> 
    <li>iOS:以<code>tidevice</code>库举例,执行命令 <code>tidevice list</code>,检查设备列表中是否包含测试设备</li> 
   </ul></li> 
  <li><p>下载安装测试包</p> 
   <ul> 
    <li>Android:框架会通过<code>config</code>中配置的<code>packagePath</code>自动下载测试包并安装(请确保手机已经打开”允许安装未知来源“ ),也可手动下载安装。</li> 
    <li><p>iOS:</p> 
     <ol> 
      <li>请手动下载演示APP进行安装</li> 
      <li><p>开启wdaproxy</p><pre><code class=\"shell\"> tidevice --udid 
$udid wdaproxy -B $web_driver_angnt_bundle_id -p $port</code></pre></li> 
     </ol></li> 
   </ul></li> 
 </ol> 
 <h3>Web</h3> 
 <p>Web项目执行前,先检查浏览器环境是否已安装</p> 
 <pre><code class=\"bash\"># 查看支持安装的浏览器
playwright install --help

# 不带参数的运行,将安装默认所有的浏览器
playwright install

# 通过提供一个参数来安装特定的浏览器
playwright install webkit
</code></pre> 
 <h2>运行</h2> 
 <p>你可以很方便的通过 cli 切换执行环境, 筛选case和控制并发数量,下面列出了一些常用命令</p> 
 <pre><code class=\"bash\"># 查看运行项目时支持的操作
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></pre> 
 <h2>配置</h2> 
 <p>以下是各端运行前必须的配置项</p> 
 <ul> 
  <li>Android配置项:deviceId、packageName</li> 
  <li>IOS配置项:platform、deviceId、packageName、webDriverAgent、</li> 
  <li>Web配置项:platform、browserType、headless</li> 
 </ul> 
 <p><span class=\"img-wrap\"><a href=\"https://img.it610.com/image/info9/c2231b2f060240a186f266c71a7cf225.jpg\" target=\"_blank\"><img class=\"lazy\" alt=\"跨端跨框架 UI 自动化测试方案 Flybirds_第3张图片\" title=\"image\" src=\"https://img.it610.com/image/info9/c2231b2f060240a186f266c71a7cf225.jpg\" width=\"650\" height=\"492\" style=\"border:1px solid black;\"></a></span></p> 
 <h2>自定义框架扩展</h2> 
 <p>Flybirds的插件式设计模式,保留了良好的扩展,未来我们会开放更多。</p> 
 <h3>修改扩展</h3> 
 <p>如果你希望在项目中修改当前扩展,你可以用本地文件替换plugin下面的(app,device,element,app,step,screen,screen_record),并在 \"plugin_info.json\" 中做相应配置。</p> 
 <p>比如你希望修改web中screen.py文件:</p> 
 <pre><code>1. 在本地创建一个py文件命名为 screen.py
2. 在plugin_info.json 的web中添加如下配置:</code></pre> 
 <pre><code class=\"json\">  \"screen\": {
  \"path\": \"{local_path}/screen.py\",
  \"ns\": \"screen.plugin.myextend\"
  }</code></pre> 
 <blockquote>
   {local_path} 为本地路径,\"ns\"为包名,注意包名的唯一性(以上包名只是例子不做强制限制) 
 </blockquote> 
 <h2>内部增强包</h2> 
 <p>对于团队内部通用的自定义功能,可以考虑创建一个extend package,Flybirds支持动态加载,package命名包含“-flybirds-plugin”即可。 携程机票内部,针对DevOps的各类工具,增强包中都进行了对接,安装后就可以使用。</p> 
 <h2>持续集成</h2> 
 <p>cli提供的命令行执行模式,可以非常方便加入各种持续集成工具.</p> 
 <p>以Jenkins为例:</p> 
 <pre><code class=\"bash\"># 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></pre> 
 <h2>发版计划</h2> 
 <p>我们将按照 SemVer 版本控制规范进行发版。逐步新增功能和代码优化,非常欢迎您加入到我们的共建计划中,在 GitHub 上提出您的宝贵建议,以及在使用时遇到的一切问题,我们也会对此每周进行一次小版本的迭代。您也可以在这里给我们精神支持,点上一颗 Star。</p> 
 <h2>参考链接</h2> 
 <ul> 
  <li>GitHub地址:<a href=\"https://link.segmentfault.com/?enc=tWO3%2BzTj6SjWSvYfwV2fRw%3D%3D.hk08%2BTCM0%2B9QwQL5y4PdmrNmTFcHWGGGcpt5KJm1h4f0oMx4%2BWkwWWbEuKy5PWbF\" rel=\"nofollow\">https://github.com/ctripcorp/...</a></li> 
  <li>PyPI地址:<a href=\"https://link.segmentfault.com/?enc=nrkcxDMQN%2BfkoFB%2B8Gwl1w%3D%3D.rXIl%2Fyam9g1%2BLublFachkxk6xoGBCKGmmR8PEjKuYTg%2FgT9gkOrGSOtAN6EI7rrE\" rel=\"nofollow\">https://pypi.org/project/flyb...</a></li> 
  <li>Pages:<a href=\"https://link.segmentfault.com/?enc=7PgM2Ma4BMNKiYHX%2BqFIwA%3D%3D.dVraaTRLIs1OGDnTQYndUPHi9v7gu3JYGGM1qc2%2BAQ8yEHBudBMjwl3c34Sep7wH\" rel=\"nofollow\">https://ctripcorp.github.io/f...</a></li> 
  <li>PlayWright: <a href=\"https://link.segmentfault.com/?enc=JBi%2BwmAM10Ha%2Feh%2BFtqHpw%3D%3D.eioXwLz3SCCrDsJp%2BJNM44Feajm7JIQwg8ZprfHHhpQIjWdTiySRcP4An7LHHTrG\" rel=\"nofollow\">https://github.com/microsoft/...</a></li> 
  <li>Airtest: <a href=\"https://link.segmentfault.com/?enc=SjbvhHXHXgG2IaQDJ04MrA%3D%3D.Hq25fT9HGUwssc4j3U4XFMwDgFtWE4GzzY%2B1Nr%2FPUy8HW1VNDJPh1gausOlscD%2BK\" rel=\"nofollow\">https://github.com/AirtestPro...</a></li> 
  <li>Behave: <a href=\"https://link.segmentfault.com/?enc=By67gJ%2Fv2cGevJZsjCmm1w%3D%3D.NIQ4q4fDZ9iBfbbKapoplHf73HOuxBoFqymRPAYv%2BOoEHtpG6YpHmX2Emw69Aqam\" rel=\"nofollow\">https://github.com/behave/behave</a></li> 
  <li>欢迎在 GitHub <a href=\"https://link.segmentfault.com/?enc=TCHi4veIu9%2FPKsVz68i9Ng%3D%3D.aq0jFBB7rCdIsHQTB4dcxO8SL9%2BzwSigbZf7DmDl4sXF28rUm4NyizovOaJWQYZ2\" rel=\"nofollow\">issues</a> 和<a href=\"https://link.segmentfault.com/?enc=cSquL8ZiLLwCOJNjUytgqQ%3D%3D.QsctS36dgiKv4A7y7xpbjX9zfXRiHunp87MjBN5OHCyTNP4O6Adq7zjDKpKxK4t292uqg9PJKAC4zsX4UBBs0g%3D%3D\" rel=\"nofollow\">Discussions</a>区提问</li> 
  <li>支持邮箱:<a href=\"mailto:flybirds_support@trip.com\">flybirds_support@trip.com</a></li> 
 </ul> 
</article>
                            </div>
                        </div>
                    </div>                </div>
            </div>
            <div class="col-xs-12 col-lg-3 list1">
                <h3 class="h4 relate-title">相关推荐</h3>

                                <p><a href="/show/1/14357.html">【云原生】K8S--负载均衡详细介绍;什么是K8S的负载均衡?</a></p>
                                <p><a href="/show/1/7304.html">吃瓜笔记:Task01 绪论、模型评估与选择</a></p>
                                <p><a href="/show/1/14914.html">Java递归实现评论多级回复</a></p>
                                <p><a href="/show/1/15791.html">我和爸爸赌输赢</a></p>
                                <p><a href="/show/1/11178.html">解决Hive on Spark与Spark on Hive之间表数据不互通问题</a></p>
                                <p><a href="/show/1/11283.html">微信小程序如何实现转发/分享功能</a></p>
                                <p><a href="/show/1/14428.html">ES6中的(...)运算符详细学习</a></p>
                                <p><a href="/show/1/18504.html">经典同态加密算法(加法与乘法)</a></p>
                                <p><a href="/show/1/18306.html">IP地址是什么</a></p>
                                <p><a href="/show/1/6787.html">Room:又要写业务代码了?看看我吧,给你飞一般的感觉!</a></p>
                                <p><a href="/show/1/14155.html">机器学习之西瓜书+南瓜书:第三章 线性模型</a></p>
                                <p><a href="/show/1/6191.html">Vue 3是一个错误,我们不应该再犯。</a></p>
                                <p><a href="/show/1/11477.html">【做项目】基于SpringBoot从零开发的个人博客 —— 从技术选型到部署实战(附学习路线)</a></p>
                                <p><a href="/show/1/7384.html">Python的一些列表功能</a></p>
                                <p><a href="/show/1/12870.html">docker部署mysql集群</a></p>
                                <p><a href="/show/1/7789.html">狂神。Mybatis学习。</a></p>
                                <p><a href="/show/1/15561.html">华为昇腾MindSpore训练过程经验分享——D-Linknet</a></p>
                                <p><a href="/show/1/14835.html">万字综述,核心开发者全面解读PyTorch内部机制</a></p>
                                <p><a href="/show/1/13023.html">IDEA如何运行SpringBoot项目(超详细截图)</a></p>
                                <p><a href="/show/1/15613.html">Hugging Face创始人亲述:一个GitHub史上增长最快的AI项目</a></p>
                            </div>
        </div>
    </div>


            <div class="container text-center" style="padding-top: 15px;">
                <p>
                    <a href="/">ItVuer</a> - <a href="#">免责声明</a> - <a href="#">关于我们</a> - <a href="mailto:561261067@qq.com">联系我们</a>
                </p>
                <p>本网站信息来源于互联网,如有侵权请联系:561261067@qq.com</p>
                <p><a href="https://beian.miit.gov.cn/" target="_blank">桂ICP备16001015号</a></p>
            </div>
        </div>
    </div>
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="/static/js/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="/static/bootstrap-3.4.1/js/bootstrap.min.js"></script>    
    <script type="text/javascript">
        $('img').attr("src",'/static/1.jpg').attr('height','1').css('border','0');
        // function imgError() {
        //     $('img').error(function(){
        //         $(this).attr('src', "/static/1.jpg");
        //     });
        //     console.log('imgError');
        // }
        // imgError();
        // setTimeout(imgError, 2000);
    </script>
</body>
</html>