目录:

概述

为了避免每次上线前重复的人工回归测试,保证每次上线的版本不会引起核心业务的不稳定,所以急需自动化测试来保证业务的稳定性.经过调研我尝试使用Appium进行自动化测试,原因是功能强大,跨平台而且社区也很活跃.

主流框架对比

Appium优点

  • 开源
  • 跨架构:Native App、Hybird App、Web App
  • 跨设备:Android、iOS、Firefox OS
  • 不依赖源码
  • 使用任何 WebDriver 兼容的语言来编写测试用例。比如 Java, Objective-C, JavaScript with Node.js (in both callback and yield-based flavours), PHP, Python, Ruby, C#, Clojure, 或者 Perl.
  • 不需要重新编译APP

如果有不清楚WebDriver的小伙伴马上在Appium架构介绍中会有说明.

Appium理念

  1. 你无需为了自动化,而重新编译或者修改你的应用。
  2. 你不必局限于某种语言或者框架来写和运行测试脚本。
  3. 一个移动自动化的框架不应该在接口上重复造轮子。(移动自动化的接口应该统一)
  4. 无论是精神上,还是名义上,都必须开源。

Appium架构

iOS: 苹果的UIAutomation
Android 4.2+: Google的UiAutomator
Android 2.3+: Google's Instrumentation. (由单独的项目Selendroid提供支持 )

Appium 1.6版本以上增加了UiAutomator2

为了满足上面跨平台,把这些三方框架封装成一套API —— WebDriver Api(客户端到服务端的协议)

事实上 WebDriver 已经成为 web 浏览器自动化的标准,也成了 W3C 的标准 —— W3C Working Draft,所以Appium在原有基础上扩充了移动自动化相关的API.

投资 WebDriver 意味着你可以押宝在一个已经成为标准的独立,自由和开放的协议。你不会被任何专利限制。

核心架构: Appium使用C/S架构,运行时候Service端会监听Client端发送的命令,接着在移动设备上执行这些命令,然后将执行结果放在 HTTP 响应中返还给客户端.

基于这架构可以做什么?

  • 可以用任何实现了该客户端的语言来写测试代码
  • 可以把服务端放在不同的机器上
  • 可以只写测试代码,然后利用类似 saucelabs 云服务来解释命令.

下图解释了云服务的具体作用:

海量免费学习资料,软件测试交流:1140267353,还会有同行一起技术交流)

Appium 使用

服务端

  • 安装Appium服务器

      npm install -g appiumnpm install -g appium-doctorappium-doctor
    复制代码

其中appium-doctor用来检查电脑是否缺少相关依赖.当所有都是对勾表示Appium环境配置完毕,如下:

  • 开启appium服务器:

      appium --address 127.0.0.1 --port 4723 --log "/Users/mio4kon/Desktop/appium.log" --log-timestamp --local-timezone --session-override
    复制代码

客户端

再次强调 Appium 支持各种语言,这里我选择JAVA.如果觉得JAVA语法不够简洁或者不熟悉,可以使用你所熟悉的语言.

创建 MAVEN/Gradle 工程:

创建工程,并加入下面依赖:

        <dependency><groupId>io.appium</groupId><artifactId>java-client</artifactId><version>5.0.0-BETA2</version><exclusions><exclusion><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.0.1</version></dependency>
复制代码

这样Appium 客户端的依赖就引入成功了.

Capabiltiy配置:

每个Test的基类中定义setUp方法,并设置Capabiltiy以前其他的初始化操作:

DesiredCapabilities capabilities = new DesiredCapabilities ();
capabilities.setCapability (MobileCapabilityType.DEVICE_NAME, deviceName);
capabilities.setCapability (MobileCapabilityType.PLATFORM_NAME, platformName);
capabilities.setCapability (MobileCapabilityType.PLATFORM_VERSION, platformVersion);
capabilities.setCapability (MobileCapabilityType.APP, apkPath);
capabilities.setCapability (AndroidMobileCapabilityType.APP_PACKAGE, appPackage);
capabilities.setCapability (AndroidMobileCapabilityType.APP_ACTIVITY, appActivity);
capabilities.setCapability (MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);复制代码

这里我使用的是 TestNG 中的Parameters注释来配置参数.

TestNG 又是什么鬼? 简单来说TestNG是java的一个测试框架,类似JUnit但功能更加强大,使用也方便.

TestNG

利用TestNg的一些注释,做准备化和收尾操作.

上面的setUp方法我就使用了BeforeClassParameters这两种注释.

    @BeforeClass@Parameters({"driverName", "url", "deviceName", "platformName", "platformVersion", "apkPath", "appPackage", "appActivity"})public void setUp(String driverName, String url, String deviceName,String platformName, String platformVersion, String apkPath,String appPackage, String appActivity) throws Exception {log.i (TAG, "BeforeClass");driver = setRemoteDriver (driverName, url, deviceName, platformName, platformVersion, apkPath, appPackage, appActivity);actions = ElementActions.getInstance ().init (driver);assertActions = actions.getAssertActions ();Screenshot.getInstance ().init (driver);prepare ();}
复制代码

同样在在AfterClass后,进行了driver的退出.

正常情况下我们写测试用例是下面这种情况:

一个TestClass中包含多个TestMethod.如果每个TestMethod都相互独立,需要重新运行APP显然非常耗时,所以这里我将每一个TestClass相互独立,而其中的TestMethod又相互依赖,执行顺序通过TestNG的XML来控制.如下:

   <test name="XX测试"><classes><class name="XXTest"><methods><include name="testAAA"/><include name="testBBB"/><include name="testCCC"/></methods></class></classes></test>
复制代码

但是有些情况如果需要TestMethod也相互独立的话,可以利用AfterMethod注释.

    @AfterMethodpublic void afterMethod() {driver.resetApp ();}
复制代码

编写用例

查找元素

定位方式

查找元素可以通过很多方法(可以通过UIAutomatorViewer获取页面的id,name等信息):

  • id
  • name
  • className
  • xpath
  • uiautomator

高级定位

  • xpath查找登录按钮:

      by.xpath ("//button[@name='login']")
    复制代码

xpath实例教程

  • uiautomator的API滚动查找:海量免费学习资料,软件测试交流:1140267353,还会有同行一起技术交流
 String rule = "new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().textContains(\"" + locator.value + "\"))"WebElement cl = driver.findElementByAndroidUIAutomator(rule));
复制代码

其实就是用如果用uiautomator来写:

new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().textContains(value));
复制代码

uiautomator API

 ### 元素管理
复制代码

为了让测试用例能够方便复用,简化写用例的时间,必要的封装是不可少的. 利用 Page Object 模式将页面上的元素进行封装.这样所有 Test 只需要简单的控制页面元素即可.

  • 可以使用yaml文件进行管理页面元素:

然后在BasePage中将yaml解析封装成Locator对象.并保存到集合.
这样所有的PageObject都可以通过下面方法来定位元素.

protected Locator getLocator(String locatorName) {checkNotNull (locatorName);Page page = getPage ();List<Locator> locators = page.locators;for(Locator locator : locators) {if (locatorName.equals (locator.name)) {return locator;}}return null;}public Locator 请输入手机号 = getLocator ("请输入手机号");
public Locator 请输入验证码 = getLocator ("请输入验证码");
public Locator 发送验证码 = getLocator ("发送验证码");复制代码

TODO: 用工具生成对应page类
之所这么做是可以在用的时候直接通过IDE提示有哪些控件,但是写上述代码缺都是无聊的操作,所有我用了 freemarker 自动解析yaml来生成对应Page类,如下:

         Map<String, Object> input = new HashMap<String, Object> ();input.put ("pageName", page.pageName);List<LocatorObject> genLocators = new ArrayList<> ();List<Locator> locators = page.locators;for(int i = 0; i < locators.size (); i++) {System.out.println ("生成Locator:" + locators.get (i).name);genLocators.add (new LocatorObject (locators.get (i).name, locators.get (i).name));}input.put ("locators", genLocators);Template template = cfg.getTemplate ("page-temp.ftl");Writer fileWriter = new FileWriter (new File (path, page.pageName + ".java"));try {template.process (input, fileWriter);} finally {fileWriter.close ();}
复制代码

如果不会用 freemarker的可以搜索下相关资料.

元素交互

将交互事件,封装在ElementActions中.使用起来非常简单:

actions.text (loginPage.请输入手机号, phone);
actions.click (loginPage.发送验证码);
actions.text (loginPage.请输入验证码, pwd);
actions.click (loginPage.登录);
复制代码

常用的交互事件:单击,连击,上下左右滑动,后退,输入文本等等.

上面元素定位其实只是封装Locator,并没有真正的查找元素,查找元素实际上是在ElementActions中处理的.由于应用经常处理网络请求,控件有时候需要过段时间才可见,所以在查找控件时候需要给予一定的时间.

        WebElement element;try {element = (new WebDriverWait (mDriver, locator.timeOutInSeconds)).until (new ExpectedCondition<WebElement> () {@Overridepublic WebElement apply(WebDriver driver) {List<WebElement> elements = getElement (locator);if (elements.size () != 0) {return elements.get (0);}return null;}});} catch (NoSuchElementException | TimeoutException e) {log.e (TAG, "超时[%4$d秒],找不到元素:[%1$s] , [By.%2$s : %3$s]", locator.name, locator.type, locator.value, locator.timeOutInSeconds);throw e;}
复制代码

断言

同样为了使用方便讲常用的断言封装,如Toast验证等.

    public void validatesToast(final String msg) {checkNotNull (msg);final WebDriverWait wait = new WebDriverWait (mDriver, 10);assertNotNull (wait.until (ExpectedConditions.presenceOfElementLocated (By.xpath (String.format ("//*[@text=\'%s\']", msg)))));}复制代码

测试报告

测试报告可以直观的展示测试的成功率,截图等信息.这里选择extentreports做为测试报告的框架.

最终效果:

踩坑

  • findElementByName无效.

Searching by name was deprecated over a year ago and removed from 1.5. In general, searching by accessibility id is better for a variety of reasons.

如上findElementByName这个方法从Appium 1.5之后删除了,但是API不经能找到并且也没提示过时.这不坑爹嘛.后来使用下面的代码才解决用name查找元素的方法.

 String query = "new UiSelector().textContains" + "(\"" + locator.value + "\")";webElements = mDriver.findElementsByAndroidUIAutomator (query);
复制代码
  • 据说Appium 1.6.3可以查找 Toast 的信息了.然后屁颠屁颠的跑去试了下网上的例子发现不好使啊.一度以为是Client版本的问题.搞了半天才发现需要加下面的代码:
capabilities.setCapability (MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
复制代码

(感觉现在的Appium文档不全而且有点乱

  • 无意中发现测试的时候高德地图弹Toast报错.然后直接编译安装却不保存.猜测是不是在安装过程中Appium改了啥.看了下Service日志,竟然在安装的时候重新签名...
App not signed with debug cert.
2017-02-13 18:17:19:848 - info: [debug] [ADB] Resigning apk.
2017-02-13 18:17:23:938 - info: [debug] [ADB] Zip-aligning 'app-debug.apk'
2017-02-13 18:17:23:958 - info: [ADB] Checking whether zipalign is present
2017-02-13 18:17:23:964 - info: [ADB] Using zipalign from /Users/mio4kon/Library/Android/sdk/build-tools/25.0.2/zipalign
2017-02-13 18:17:23:968 - info: [debug] [ADB] Zip-aligning apk.
2017-02-13 18:17:24:104 - info: [AndroidDriver] Remote apk path is /data/local/tmp/463eb03788048b4a1dacfe28545ee76e.apk
复制代码

解决方法:

capabilities.setCapability (AndroidMobileCapabilityType.NO_SIGN, true);

最后感谢大家的观看,如果对自动化感兴趣请点赞关注收藏!!!

里面有自动化测试学习资料,面试宝典等等,还有测试大牛就交流。

自动化之旅--Appium相关推荐

  1. 美团Android自动化之旅—适配渠道包

    概述 前一篇文章(美团Android自动化之旅-生成渠道包)介绍了Android中几种生成渠道包的方式,基本解决了打包慢的问题. 但是,随着渠道越来越多,不同渠道对应用的要求也不尽相同.例如,有的渠道 ...

  2. python docker自动化_「docker实战篇」python的docker爬虫技术-移动自动化控制工具appium工具(17)...

    原创文章,欢迎转载.转载请注明:转载自 IT人故事会,谢谢! 原文链接地址: 「docker实战篇」python的docker爬虫技术-移动自动化控制工具appium工具(17) Appium是一个开 ...

  3. 自动化测试之路 —— Appium安装教程

    阅读目录 1.目的 2.说明 3.环境准备 3.1 安装nodejs 3.2 安装JDK 3.3 安装Android SDK 4. 安装Appium 4.1 下载 4.2 安装 4.3 启动 4.4 ...

  4. Android自动化之旅—生成渠道包

    概述 每当发新版本时,美团团购Android客户端会被分发到各个应用市场,比如豌豆荚,360手机助手等.为了统计这些市场的效果(活跃数,下单数等),需要有一种方法来唯一标识它们. 团购客户端目前通过渠 ...

  5. 美团Android自动化之旅—生成渠道包

    每当发新版本时,美团团购Android客户端会被分发到各个应用市场,比如豌豆荚,360手机助手等.为了统计这些市场的效果(活跃数,下单数等),需要有一种方法来唯一标识它们. 团购客户端目前通过渠道号( ...

  6. APP自动化学习之appium认识

    系列文章目录 文章目录 系列文章目录 前言 1. 安装Java 2. 安装SDK 2.1 下载 2.2 解压 2.3 脚本升级 2.4 配置环境变量 3. 安装Appium 3.使用 4. 元素定位与 ...

  7. APP自动化基础之appium

    appium介绍 什么是appium? (官方)appium是一个开源的测试自动化框架,可以与原生的.混合的和移动的web应用程序一起使用.它使用webDriver协议驱动ios.android.wi ...

  8. 自动化工具之Appium工具简单介绍

    背景 自动化,性能测试,接口测试,开发平台等工作,到底测试的价值在哪里,其实价值来源不断充实与为大众服务,今天简单介绍ui小工具appium攻击. 简单介绍 Appium 是一个自动化测试开源工具,支 ...

  9. python手机自动化截图_Python Appium自动化测试 屏幕截图

    Time will tell. 在实际自动化项目运行过程中,很多时候 App 可以会出现各种异常,为了更好的定位问题,除了捕捉日志我们还需要对运行时的设备状态来进行截屏,从而达到一种 "有图 ...

最新文章

  1. 夯实JavaScript基础之prototype, __proto__, instanceof
  2. Java对异常处理或抛出之后,后面代码会不会再执行?
  3. VTK修炼之道50:图形基本操作进阶_网格模型的特征边 与 封闭性检测
  4. 【转】java单例模式的实现
  5. 9.数据库中的子查询
  6. 菜鸟linux的sed,Linux sed命令菜鸟入门
  7. python3学习笔记 雨痕_Python 3 学习笔记:数字和布尔
  8. 把一个sql where表达式转化为一个二叉树
  9. 两个系统交互方式有几种_创新性OriginOS系统,打造个性化交互方式,很给力
  10. html5抖动效果代码,JS文字抖动特效代码
  11. dpdk X710 VF reset
  12. ArcGIS 地类净面积计算工具
  13. GoFrame+vue的前后端分离开源项目
  14. 气象信息无线监测采集系统
  15. PMP子过程定义总结
  16. 想做IT行业项目管理,面向客户方向的,考ITIL和PMP哪个更好一些?
  17. 亲测有效sudo: /etc/sudoers is world writable sudo: no valid sudoers sources found, quitting sudo: una
  18. 强化学习 11 —— REINFORCE 算法推导与 tensorflow2.0 代码实现
  19. Java课程设计-图书借阅管理系统
  20. 南京计算机与软件学院,南京信息工程大学 计算机与软件学院 刘 琦

热门文章

  1. JavaFX简单音乐播放器
  2. 微信公众账号第三方平台全网发布源码(java)- 实战测试通过
  3. 国企数字化转型主要工作
  4. 关于BeanUtils.populate()方法使用时的报错解决
  5. 嵌入式(FS_4412 ADC实验)
  6. 【Java实现学生管理系统】
  7. 计算机网络课设路由器,计算机网络课程设计---小型校园网络设计.doc
  8. textcnn文本词向量_基于Text-CNN模型的中文文本分类实战
  9. 自动化运维神器——Ansible
  10. 简易超声波雷达的arduino实现