TA的每日心情 | 郁闷 2022-8-29 14:43 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]测试小兵
|
前言
做Android端功能自动化已有2年多的时间了,使用过的功能自动化框架有Robotium、Uiautomator、
Appium。最近研究自动化case复用的方案,调研了Appium的自动化框架,并将其应用到银行一账
通的标版中,本文详细介绍基于Appium的Android功能自动化实战经验。主要包括以下几方面内容:
Appium框架原理介绍
Appium框架常用API介绍
基于Appium框架的自动化开发环境搭建
自动化case开发及分层结构设计
自动化测试用例书写规范及注意事项
功能自动化接入持续集成方案
Android常用功能自动化框架比较
下表给出Robotium、Uiautomator、Appium三种框架的比较。
了解各个自动化框架的特性,结合产品自身特点,选取一个合适的框架尤为重要。
Appium框架原理介绍
Appium 是一个开源、跨平台的自动化测试工具,用于测试原生和轻量移动应用,支持iOS, Android 和
FirefoxOS 平台。Appium 驱动苹果的 UIAutomation 库和 Android 的 UiAutomator 框架,使用 Selenium
的 WebDriver JSON 协议。下图是Appium在Android端的原理架构图
从图中可以看出,Appium Client是对webdriver原生api的一些扩展和封装,它配合原生的webdriver来使
用,二者缺一不可。Appium Server有两个主要功能:首先它作为一个http服务器端,接收从Appium
Client发送过来的命令(可以认为是case中的具体操作)。其次,它作为bootstrap客户端,在接收Client
的命令后,通过socket方式,把这些命令发给目标android机器的bootstrap来驱动Uiautomator执行自动
化操作。关于Appium的工作原理,网上资料很多,不再详细介绍,可参考如下链接
http://www.2cto.com/kf/201410/347851.html
http://www.blogjava.net/qileilove/archive/2014/12/23/421659.html
Appium框架常用API介绍
Appium的API包含在Appium Client中,下表给出不同语言平台对应的Client下载地址
下表给出Java平台的常用API,其他API可自行百度或查看Client源码
Appium元素定位和操作的api是分开的,这点与robotium框架不同,与Google新推出的iOS端功能自动
化框架EarlGrey是类似的。关于元素定位的api需要注意:当成功定位到元素时,返回WebElement对象,
但是若不能定位到元素,此api直接报错,而不是返回NULL。这对“判断某个控件是否存在”这样的常用
操作经常容易出错,比如用如下代码判断登录按钮是否存在。
- public boolean isLoginButtonShow(){
- WebElement wl = DriverManager.getInstance().findElementById(packagename
- + ":id/login_input_account");
- return wl.isDisplayed();
- }
复制代码 当登录按钮存在时,返回true,但若登录按钮不存在时,以上代码并不会返回false,而是在第2行直接崩溃。
可通过try catch捕获异常,修改如下:
- public boolean isLoginButtonShow(){
- try{
- WebElement wl = DriverManager.getInstance().findElementById(packagename
- + ":id/login_input_account");
- return wl.isDisplayed();
- }catch (Exception e){
- return false;
- }
- }
复制代码 基于Appium框架的自动化开发环境搭建
万事开头难,自动化开发环境的搭建会比较麻烦。以下详细讲解如何在mac os操作系统下,搭建基于
Appium的自动化开发环境。
1、Android开发环境搭建(JDK/SDK/AndroidStudio)请自行百度,所需安装包可在如下网页中下载:
http://tools.android-studio.org
Appium for mac安装可参考以下连接:
http://www.cnblogs.com/oscarxie/p/3894559.html
其中appium 的安装,建议使用dmg安装,点击下载安装包。“npm install -g appium”命令行安装亲测
一直报错,翻墙了也报错。
2、AndroidStudio中新建android工程AppDemo。
3、创建java module(appium):new—>new module—>java library,此java工程用来开发自动化
case。
4、安装Appium Client:创建java module (selenium),libs目录中导入相关selenium包,点击下载
selenium压缩包
5、appium module添加selenium依赖:file—>project structure—>modelues选中appium—>dependencies
添加selenium module。
6、appium module中,新建java class,开始开发自动化case。至此AppDemo工程目录结构如下所示:
7、启动appium server(命令行或者图形界面启动),注意,启动时Android Settings中请勾选No
Reset选项,可防止每次执行case时,都重新安装app,如下所示。
8、case执行,可通过IDE和脚本两种方式执行case
IDE方式:case名右击—>run
脚本方式:auto_run.sh,见下方
- #!/bin/bash
- #auto_run.sh
- source ~/.bash_profile
- cd ./AppDemo
- gradle clean
- gradle build
- export CLASSPATH=$APPIUM_HOME/java-client-3.3.0.jar:$APPIUM_HOME/selenium-java-2.48.2-srcs.jar:$APPIUM_HOME/selenium-java-2.48.2.jar:$APPIUM_HOME/junit-4.12.jar:$APPIUM_HOME/hamcrest-core-1.3.jar:$APPIUM_HOME/libs/*
- cd ./appium
- java -classpath $CLASSPATH:./build/libs/appium.jar org.junit.runner.JUnitCore com.incito.appiumdemo.cases
复制代码 其中CLASSPATH需要设置为Appium Client所在路径,
com.incito.appiumdemo.cases.PersonalCenter为case所在类,脚本的执行方式有利于自动化接入持续
集成和平台化。
至此基于Appium的自动化开发环境搭建完成,下一节介绍如何开发自动化case及case的分层结构设计。
基于Appium的自动化case开发及case分层结构设计
首先为每条case创建一个公共的基类AppiumTestBase,内含setup和teardown两个方法,以后每条case
继承该基类即可。代码如下:
- public class AppiumTestBase {
- public WebDriverWait webwait;
- private AndroidDriver driver;
- @Before
- public void setUp() throws Exception {
- File classpathRoot = new File(System.getProperty("user.dir"));
- File appDir = new File(classpathRoot, "apps");
- File app = new File(appDir, Config.CURRENT_BANK);
- DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("deviceName",Config.DEVICE_NAME); capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); capabilities.setCapability(CapabilityType.VERSION, "5.0.1"); capabilities.setCapability("platformName", "android");
- capabilities.setCapability("app", app.getAbsolutePath());
- capabilities.setCapability("udid", Config.DEVICE_NAME);//adb devices获得的值
- driver = new AndroidDriver(new URL("http://127.0.0.1:"+Config.APPIUM_PORT+"/wd/hub"), capabilities);
- webwait = new WebDriverWait(driver,10);
- DriverManager.init(driver);
- DriverManager.initWebWait(webwait);
- driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
- }
- @After
- public void tearDown() throws Exception {
- driver.quit();
- }
复制代码 setup操作包含导入待测应用apk包,设置与Appium Server连接所需参数,并初始化AndroidDriver
对象。以标版登录case为例,其需要继承AppiumTestBase,代码如下:
- package com.incito.appiumdemo;
- import org.junit.After;
- import org.junit.Before;
- import org.openqa.selenium.remote.CapabilityType;
- import org.openqa.selenium.remote.DesiredCapabilities;
- import org.openqa.selenium.support.ui.WebDriverWait;
- import java.io.File;
- import java.net.URL;
- import java.util.concurrent.TimeUnit;
- import io.appium.java_client.android.AndroidDriver;
- public class AccountLogin extends AppiumTestBase{
- /**
- * case 编号 AccountLogin_001
- * ****@throws ****Exception
- */
- @Test
- public void testAccountLogin() throws Exception {
- Account.*getInstance*().gotoLoginPage();
- Account.*getInstance*().doLogin();
- }
- /**
- * case 编号 AccountLogin_002
- * ****@throws ****Exception
- */
- @Test
- public void testLoginout() throws Exception {
- Account.*getInstance*().gotoGestureLoginPage();
- Account.*getInstance*().doGestureLogin(Config.*CURRENT_USERNAME*);
- Personal.*getInstance*().doLogout();
- }
复制代码 testAccountLogin Case中,执行了两步操作:进入登录页面;执行登录操作。这两步操作都封装在
Account类里面。由此引入自动化case的分层设计框架,如下图:
自动化开发过程中,经常遇到的一个问题是,随着产品的不断更新迭代,APP的UI会不断发生变化,
自动化如何去应对这样的变化,如何降低其维护代价。case分层设计主要是基于自动化可维护性的
考虑,可维护性是功能自动化最重要的评价指标之一,其直接决定了自动化是否能开展下去。试想
case数量达到一定程度时,若没有采用封装、分层的设计思路,极有可能出现“牵一发而动全身”的
问题。下图是标版自动化case的分层目录图。
|
|