一、什么是自动化测试,了解自动化测试
所谓的自动化测试就是前期通过人肉编码,完成测试框架,后期解放双手自动完成规定的测试流程。
自动化测试主要分为三层:UI层、接口层、单元层。
移动端、web端通常所说的自动化测试是指UI层测试,基本原理就是:基于页面元素的识别和定位来模拟用户行为,首先识别到某个元素,比如一个按钮,然后定义一个动作,比如点击,这样就通过代码模拟完成了一次按钮的点击,代替了人工去点击。如果后期再加入数据驱动和Page Object思想就基本可以形成一个UI层自动化测试框架了。
目前我觉得UI层测试有以下几点问题:
版本迭代UI变化太快,导致脚本也需要不断的更新,目前在泰然金融项目中,只针对主流程编写了测试脚本,UI变化带来的问题暂未体现。
见效慢,初期还是有一定的学习成本,包括搭建环境,编写脚本,熟悉测试框架以及设计模式。但是我相信后期自动化测试带来的效果也是非常可观的。
APP端、web端编码可能不够规范,导致很多元素定位和识别非常困难。
总的来说UI自动化测试可能更适合于主流程的测试,就是一些非常重要并且不会频繁变化的流程,对主流程做自动化回归测试,可以有效避免线上重要功能出现bug。
常见自动化测试方案介绍:
iOS:
iOS测试分为UI和Unit测试,Unit测试一般就是用代码检测代码,因此Unit测试比较适用于一些复杂代码的检查验证,以及一些暴露在.h中的方法;UI测试就是上文所描述的。
iOS UI测试的一些常见方案:
KIF 全称是Keep it functional。它是一个建立在XCTest的UI测试框架,通过accessibility来定位具体的控件(所以在编码的时候一定要设置AccessibilityLabel和AccessibilityTrait),再利用私有的API来操作UI。由于是建立在XCTest上的,所以你可以完美的借助Xcode的测试相关工具(包括命令行脚本),去模拟用户输入来测试。同时也支持UIWebView的测试。
Frank 使用Ruby语言,开源内嵌Server型,通过注入Server到APP使用API,通过Server对外通信完成UI操作。支持CI持续集成,不支持UIWebView,要求测试时在应用程序内部编译。
Appium 一个开源的、跨平台的自动化测试工具,支持IOS、Android和FirefoxOS平台。
EarlGrey Google推出的iOS功能性UI测试框架,其所提供的主要特性:强大的内建同步机制,测试会在与UI进行交互前自动等待动画、网络请求等事件。
Android:
Android平台的自动化测试一般分为2个方向:
Android端的自动化测试框架
Espresso 是 Google 针对 Android 平台开源的一款 Android 自动化测试框架,主要是用于 Android App UI 自动化测试。
UI Automator
Appium
Monkey
MonkeyRunner
Robotium
Ronaorex
TestBird
(若有兴趣,请自行搜相关文档了解)
各大云测试平台(腾讯优测云测、HUAWEI开发者联盟、贯众云测试、Testin云测)
二、Appium
为什么选择Appium
Appium是一个开源、跨平台的自动化测试工具,同时支持iOS、Android、H5,接口基本一致,减少开发维护成本;
可以使用多种语言编写测试脚本(如:Ruby、C#、Java、JavaScript、OC、PHP、Python等语言);
不需要重新编译应用就可以进行测试;
不依赖项目源代码;
社区活跃,文档健全;
Appium采用Client-Server的架构设计,并采用标准的HTTP通信协议;Server端负责与iOS、Android原生测试框架交互,无需测试人员关注细节实现;
Client端基本上可以采用任意主流编程语言编写测试用例,减少了学习成本;
Appium相关概念
Client/Server Architecture:Appium是用Node.js编写的服务器,可以使用npm安装,也可以直接安装GUI工具(Appium Desktop)。Server的功能其实就是:监听一个端口,然后由Client端发来指令,将这些指令转成移动设备或者浏览器可以理解的的形式,然后由设备执行这些指令,最后把执行结果返回给Appium Server,并在Client端展示结果。Client是发起指令的设备,一般就是指测试脚本的运行环境,也就是代码,只要实现了WebDriver标准协议就可以,可以是Java、Ruby、Python、JS、OC等语言编写的代码。
Session:自动化始终围绕一个Session进行,客户端初始化一个session来与服务端交互,不同的语言最终都是给服务端发送一个JSON对象,也就是Desired Capabilities,然后服务端就会开启一个自动化的session,并返回一个session id,后续所有的请求都会带上使用这个session id。
Desired Capabilities:以key-value的形式,将配置信息转换成json对象传输给服务端,还有一个重要的作用就是告诉Server本次测试的设备环境,比如iOS、Android还是浏览器。
Appium-Server:通过npm install -g appium安装了appium之后,在命令行输入appium,就是启动了appium server
Appium-Client:appium客户端有很多语言库,Java、Ruby、Python、PHP、JS、C#、OC...这些库都实现了Appium对WebDriver协议的扩展,加入了一些方便的方法,比如swipe之类,Appium Client让我们可以更方便的写出可读性更好的测试用例。
Appium.app/.exe:分别是Mac、Windows系统下的可视化工具,可以直接查看页面的UI结构,还可以录制用户行为生成相应的测试脚本代码,对于元素定位有很大的帮助。
Appium Inspector:用例查看APP的元素结构与基本信息,还可以与元素交互,在Appium GUI工具中可以直接使用,如下图。
WebDriverAgent:Facebook推出的一款iOS移动测试框架,在iOS端实现了一个WebDriver Server,借助这个Server可以远程控制iOS设备,可以启动、关闭应用,点击、滚动视图,或者确定页面展示是否正确。支持iOS模拟器和真机。
Appium工作原理
以Mac系统为例,使用Java(java-client)编写Appium自动化测试脚本并执行,首先会请求Appium-Server,然后Server经过解析,驱动iOS/Android模拟器或者设备来执行Appium自动化脚本,Windows平台原理类似。
Appium环境搭建
目前我们是搭建了一套Appium+Java+Windows/Mac+Android Studio环境(Mac环境搭建步骤),IDE使用Android Studio,也可以用IntelliJ IDEA、Eclipse,使用Java编写测试脚本。
(Windows系统教程:https://www.testwo.com/blog/8000)
(Mac系统教程:https://juejin.im/post/5b2f291ce51d4558d217d5f6)
三、编写自动化测试脚本
元素定位
appium一些常见的定位方式(复杂元素可以配合Inspector查找):
cssSelector # Selenium 最强大的定位方法,比 xpath 速度快,但比 xpath 难上手
linkText # 链接元素的全部显示文字
partialLinkText # 链接元素的部分显示文字
name # 元素的 name 属性,目前官方在移动端去掉这个定位方式,使用 AccessibilityId 替代
tagName # 元素的标签名
className # 元素的 class 属性
id # 元素的 id 属性
xpath # 比 css 定位方式稍弱一些的定位方法,但胜在容易上手,比较好使用,缺点就是速度慢一些。
AccessibilityId # Appium 中用于替代 name 定位方式
AndroidUIAutomator # Android 测试,最强大速度最快的定位方式
iOSNsPredicateString # iOS 谓词的定位方式,仅支持 XCTest 框架,需大于 iOS 9.3或以上
IosUIAutomation # iOS 谓词的定位方式,仅支持 UIAutomation 框架,需大于 iOS 9.3或以下
iOSClassChain # 国外大神 Mykola Mokhnach 开发类似 xpath 的定位方式,仅支持 XCTest 框架,,不如 xpath 和 iOSNsPredicateString 好
windowsAutomation # windows 应用自动化的定位方式
className
使用元素的className属性定位,适用于iOS、Android
driver.findElementByClassName("XCUIElementTypeButton");
id
使用元素的resource-id属性定位,适用于Android4.2以上版本,定位简洁有效,推荐使用。
driver.findElementById("toolbar_back_btn");
xpath
iOS、Android都支持,定位速度非常慢,除非万不得已不要使用,官方也不推荐使用,但是appium框架还是支持xpath的,毕竟很多元素只能使用xpath定位。
比如金融登录页面,手机号输入框,使用xpath定位,寻找元素,并且输入手机号这个流程大概需要24秒;使用className执行这个流程只需要7秒左右。
driver.findElementByXPath("(//XCUIElementTypeOther[@name=\"确认无误\"])[2]");
xpath定位分为4种:
1.使用绝对路径定位(不推荐):
driver.findElementByXPath("className/className/className....")
2.使用相对路径定位:
driver.findElementByXPath("//className")
3.使用元素索引定位:
driver.findElementByXPath("//className[index]")
4.使用元素属性定位:
driver.findElementByXPath("//className[@label="确定"][@enable=true]")
AccessibilityId
替代name属性的定位方式,在iOS上主要是元素的label和name属性,在Android上是content-desc属性,如果label/name/content-desc为空,则不能使用AccessbilityId定位元素
driver.findElementByAccessibilityId("获取验证码");
AndroidUIAutomator
仅支持Android4.2以上系统,可使用元素的单个或者多个属性定位,支持以下属性定位:
index(int index)
text(String text)
resourceId(String id)
className(String className)
packageName(String packageName)
description(String desc)
checked(boolean val)
clickable(boolean val)
enabled(boolean val)
longClickable(boolean val)
password(boolean val)
selected(boolean val)
instance(int val)
# 其他一些详细方法(包括正则表达式匹配),请查看 Android 源码中,UiSelector 类定义的方法
例子:
MobileBy.AndroidUIAutomator("new UiSelector().text(\"确定\").clickable(true)")
iOSNSPredicate
仅支持iOS,可使用元素的单个或者多个属性定位,详细请参考iOSNSPredicate定位
手势操作
Appium提供了点击tap()、滑动swipe()、缩小pinch()、放大zoom()、移动move()等手势操作API。
设计模式
Appium通常使用Page Object设计模式,将每一个测试页面抽象为1个Page类,并在该类中封装了本页面的测试对象和基本的测试步骤,以提高代码的可读性复用性通用性和一致性。使用Page Object模式的项目结构如下图所示: