记一次Appium实战

2022-03-24 15:58:30 浏览数 (1)

前言

做或不做?

最新在做一些移动端UI自动化的工作,已经有一些成果.本次记录一下如何从0搭建UI自动化框架.

UI自动化在初创公司都不太被看好,原因有以下几点:

  • 1.功能经常改,可能一个功能模块下个版本就没有了.
  • 2.UI自动化需要专职的人写,有一定的投入成本.
  • 3.UI自动化发现不了什么问题,存在意义不大.
  • 4.其他

上述几点,目前移动端UI自动化在中小公司还没有开展或者开展的不是很好.但是随着项目发版的频率越来越高,每次发版前回归核心功能的手工测试工作量越来越大.

带来的是问题是,每次临近发版本,开发每次build一个包,测试同学就要对所有功能check一遍,毕竟临近发版不敢仅回归改动的地方,要回归所有功能.

所以移动端UI自动化还是有一定的存在必要的,只不过看公司项目的发展,一般来说项目较为稳定做比较合适.

误区

关于UI自动化能带来多少价值,这个话题一直比较有争议.

误区有以下几点:

  • 1.不能替代手工测试
  • 2.必须发现bug
  • 3.其他

价值

体现UI自动化的价值有以下几点:

  • 1.能减轻部分手工测试,比如核心模块.
  • 2.持续集成中,对每次build的app的核心模块做冒烟测试.
  • 3.持续集成中,结合性能测试.

框架选择

接触UI自动化也大概有3年左右时间了,从Robotium、Appium、Macaca到最近比较火的atx都有接触过.但是Appium在解决平台兼容性、使用规模大、文档较多相比其他框架还是有较大的优势.

当然框架的选择也是因人而异,没有绝对好和坏.

开发环境

  • 语言: java jdk1.8
  • 编译环境:maven
  • 框架:testng
  • 报告:extentreports
  • IDE:idea
  • appium client:java-client
  • appium server:1.9.0-beta.1

框架设计

先附上一张模块图

兼容

这里指的兼容性是要兼容Android主流系统和iOS主流系统.

比如Android在大于等于7.0系统,底层引擎需要使用uiautomator2,不然在获取元素会存在问题.

比如iOS底层使用是xcuitest,wda是和xcuitest进行通信.但是只有大于等于9.3版本底层才使用的xcuitest.

综上在框架设计前期,不仅需要考虑单点系统,而是需要考虑框架的能兼容多少设备版本.

复用性

现在移动端都是做Android和iOS两端,所以UI自动化也需要写两端的代码.做Android和iOS唯一不太一样的是元素定位不同,其他driver实例和公共方法调用,基本上可复用的.

后续维护

好的框架设计可以减轻后续维护成本,这里最常见的是PO封装,使模块代码和测试代码分离.

之前写的PO设计文章 https://testerhome.com/topics/15717

页面建模

把app每个页面或者多个关联的页面抽象出一个page

  • 首页底部tab导航,可提供中转功能
  • 首页大类入口,可提供中转功能
  • 首页搜索,可单独封装成一个方法
  • 并不是页面中所有的都要建模,优先核心功能

在建模页面中,appium提供页面工程模式(PageFactory)

代码语言:javascript复制
PageFactory.initElements(new AppiumFieldDecorator(driver), HomePage);

需要driver参数和当前类参数初始化当前页面

元素操作

元素定位

appium提供注解的方式声明元素,并且声明显示等元素时间

代码语言:javascript复制
@FindBy( xpath = ".//*[@text='发现']")
@WithTimeout(time = Timeout,chronoUnit = ChronoUnit.SECONDS)
public AndroidElement HomeBtn;

需要注意的是iOS元素定位的方式不是很多,优先用accessibility,万不得已采用xpath,xpath定位比较慢.

元素操作

在上边定义元素,可以直接使用click或者sendkeys操作

把homeTab封装成一个小方法,可在其他page或者case中调用

代码语言:javascript复制
/**
 * 首页tab
 */
public void homeTab() throws InterruptedException {
    HomeBtn.click();
    log_info("点击首页");
}

用例编写

用例编写应该有几个原则:

  • 每个用例步骤不易太多,太多会让case的成功率变低,应该把多步骤分摊到多个case中
  • 解耦case之间的关系,比如case1的运行结果不能影响case2执行.需要使用testng的执行顺序
  • 也就是在每个test方法,都重新重新走一次BeforeMethod方法,虽然脚本执行的整体时间增长了,但是case的稳定性会增加
代码语言:javascript复制
@BeforeMethod
    public  void  setup() throws IOException, InterruptedException
    baseDriver = driver.preiOSDriver();
    }
    

case应该直接调用page中的方法,让case变得更简洁

代码语言:javascript复制
/**
 * 测试点:首页-商城
 */
@Test(enabled = true)
public void  test_shop() throws InterruptedException {
    homePage.homeShop();
}

断言

使用testng的Assert类,可以封装一些简单的断言.

代码语言:javascript复制
 /**
     * 断言页面包含某个的元素
     */
    public void assertContain(String text) throws InterruptedException {
        PageSource = this.driver.getPageSource();
        if (PageSource.contains(text)){
            Assert.assertTrue(true);
        }else {
            Assert.assertFalse(true);
        }
    }
    
    /**
     * 断言页面包含element
     * by:元素
     */
    public void assertContainBy(By by){
        if (driver.findElements(by).size() > 0){
            Assert.assertTrue(true);
        }else {
            Assert.assertFalse(true);
        }
    }

需要注意的是,点击页面跳转以后,如果立即断言会断言失败,因为页面跳转一般是由1~3秒的页面加载,这个时候元素还没有呈现加载处理,如果获取页面元素进行断言必然会抛异常.

解决方法大致可以在每个前言加等待时间或者设置断言超时时间

失败截图

如果case中使用了断言方法,在运行多条case以后,肯定是关心case的成功或者失败,失败具体是什么原因或者当时失败的页面状态.

testng框架TestListenerAdapter类提供了成功、失败等状态的监听方法

那么可以写个类集成TestListenerAdapter方法,扩展onTestFailure方法.比如实现失败截图,可以使用base64方法把图片输出到测试报告中

测试报告

关于选用测试报告插件,testng提供了测试报告,但是不太美观.也可以使用reportng,也仅仅比testng稍微好看点.

推荐两个比较好的测试报告框架,Allure和extentreports.我目前使用的是extentreports,大致生成测试报告如下

运行

因为使用的maven,在pom中使用了maven-surefire-plugin插件,可以动态传入参数.比如运行平台、设备id、appium端口等.

另外已经把appium server做成自启动,也不需要额外启动.

代码语言:javascript复制
外部参数传入执行:

PLATFORM:设备平台 Android or iOS
UDID:设备UDID
APPIUMPORT:appium的端口
WDAPORT:wda的端口
MAILLIST:收件人地址  xxxx@163.com

mvn test -DPLATFORM=Android -DUDID=192.168.56.101:5555 -DAPPIUMPORT=4723 -DBPPORT=4724 -DWDAPORT=8003 -DMAILLIST= xxxx@163.com, xxxx@163.com

持续集成

  • 和jenkins结合,每次打包或者发版前把build的包进行UI自动化回归测试
  • 自动化任务调度,在前端页面触发UI自动化,后端执行UI自动化脚本

0 人点赞