You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
17 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 21 | 移动测试神器带你玩转Appium
在上一篇文章中我介绍了Web App、Native App和Hybrid App三种不同类型的移动应用以及对应的测试设计方法也介绍了移动应用所特有的专项测试知识。
今天我就以移动应用的自动化测试为主题介绍目前主流的移动应用自动化测试框架Appium。Appium 是一个开源的自动化测试框架支持iOS和Android上Web App、Native App和Hybrid App的自动化测试。
由于基于Appium的移动应用环境搭建相对复杂虽然网上也有不少教程但是知识点都比较零碎而且大多都是基于早期版本的示例所以我会使用最新版本的Appium Desktop 1.6.2和Appium Server 1.8.1来展开今天的内容:
* 首先我会展示如何在Mac环境下一步一步地搭建Appium测试环境
* 接下来我以iOS为例实际开发两个测试用例一个是Native App的测试用例另一个是Web App的测试用例因为Hybird App的测试用例其实是类似的Native App的壳Web App的内容所以就不再单独举例子了
* 然后我会在iOS的模拟器上实际执行这两个测试用例之所以选择iOS模拟器而不用iOS真机做例子是因为iOS真机的测试需要用到Apple开发者账号还需要对被测应用进行签名等会在环境搭建过程中引入很多额外步骤而这些步骤对于讲解Appium并没有直接的关系
* 最后当你已经通过实际使用对Appium形成感性认识后我再来简单介绍一下Appium的内部原理让你做到知其然知其所以然。
## 移动应用的自动化测试需求
在开始设计测试用例前,我们首先需要明确要开发的这两个自动化测试用例的具体测试需求。
1. Native App的测试用例被测App我选用了Appium官方的示例App被测App的源代码可以通过“[https://github.com/appium/ios-test-app”](https://github.com/appium/ios-test-app%E2%80%9D) 下载然后在Xcode中编译打包成TestApp.app。
具体的测试需求是输入两个数字然后点击“Compute Sum”验证两个数字相加后的结果是否正确。
2. Web App的测试用例具体需求是在iPhone上打开Safari浏览器访问Appium的官方主页“[http://appium.io](http://appium.io)”然后验证主页的标题是否是“Appium: Mobile App Automation Made Awesome”。
![](https://static001.geekbang.org/resource/image/39/26/391e5c3efac446b7cfc76fc1620cb626.png)
图1 Native App和Web App的GUI界面示例
接下来我将从最初的环境搭建开始和你来一起开发iOS上的Native App和Web App的测试用例。首先我们看一下iOS的环境搭建如果你之前没有接触过这部分内容你可以跟着我的步骤一步一步来做而如果你已经比较熟悉Xcode的话可以跳过这部分内容直接从“Appium环境搭建”部分看起。
## iOS环境搭建
在正式搭建Appium环境前我们先来搭建iOS开发环境
* 首先下载安装Xcode
* 然后在Xcode中下载iOS的模拟器
* 接着使用Xcode编译打包被测试App
* 最后在iOS的模拟器中尝试手工执行这两个测试用例。
在iOS模拟器中手动执行测试用例的具体操作步骤如下
1. 启动Xcode导入ios-test-app下的TestApp.xcodeproj项目。
2. 在Xcode中打开“Preferences”中的“Components”完成iOS 10.0 Simulator的下载。
3. 在Xcode的“General”页面将TestApp的“Deployment Target”设置为10.0并且将“Devices”设置为“iPhone”如图2所示。
![](https://static001.geekbang.org/resource/image/fa/83/faad103928afd3011e0c273ce3e22683.png)
图2 TestApp的General配置
4. 在Xcode中编译运行TestApp之后系统会自动启动iPhone模拟器自动完成TestApp的安装并在iPhone模拟器中自动启动TestApp。
5. 在TestApp中手动执行自定义的加法测试用例。
6. 退出TestApp然后打开Safari浏览器在Safari中执行访问Appium官方主页的测试用例。
至此你已经搭建好了iOS开发环境并且成功编译打包了TestApp。接下来我们再一起来搭建Appium测试环境并尝试在Appium中开发上述的两个测试用例。
## Appium测试环境搭建
通过Appium的官方网站下载并安装最新版本的Appium截止本文写作的时间最新版本是Appium-1.6.2.dmg。
需要注意的是早期版本和网上很多教程都建议用命令行的形式启动Appium Server但在这里我是想强调的是你完全可以通过界面启动在Launchpad中找到Appium的图标点击即可启动而且新版本的Appium也推荐这个启动方式。通过界面启动是目前最简单直接的方式。
然后你需要用命令行“npm install -g appium-doctor”安装Appium的环境诊断工具appium-doctor用于检查Appium所依赖的相关环境变量以及其他安装包是否都已经配置好了。如果还没有就需要逐个安装并根据appium-doctor的提示配置环境变量。
这里Appium最主要的依赖项主要有Java、Node.js、Xcode、Carthage、Android SDK、adb等。如果你所有的环境依赖都正常配置的话你就会看到appium-doctor返回这样一个截图如图3所示。
![](https://static001.geekbang.org/resource/image/3b/a8/3b8915195cade244fe094a37a1a295a8.png)
图3 正常配置环境依赖后appium-doctor返回的截图
按照上面的步骤配置好Appium的环境依赖后就可以继续启动Appium Server了。
## Appium Inspector的使用
为了后续测试用例的顺利执行我们可以先来熟悉一下Appium Inspector的使用。Appium Inspector主要是用来协助对界面元素进行定位的工具。
首先我们来看看如何使用Appium Inspector启动iPhone的模拟器并在模拟器上运行TestApp以及如何通过Inspector定位TestApp界面上的元素了解元素的定位是后续开发自动化脚本的基础。具体的操作过程如下。
1. 通过Appium Server的“Start Inspector Session”按钮进入Session配置界面。
![](https://static001.geekbang.org/resource/image/5a/b9/5a4a49e29f98057e75a7f18dedaac5b9.png)
图4 点击“Start Inspector Session”按钮打开Session配置界面
2. 在Session配置界面完成必要参数的配置。这里你需要根据选用的移动设备操作系统、模拟器/真机等具体情况来完成参数配置工作。需要配置的参数主要包括platformName、platformVersion、DeviceName、automationName和app。
其中automationName指自动化测试框架的名称这里采用了XCUITestapp指被测Native App的安装包路径这里使用之前Xcode打包生成的TestApp.app这样启动模拟器时就会自动把TestApp.app安装到模拟器中。
其他参数的配置非常简单,我就不再一一展开了。
![](https://static001.geekbang.org/resource/image/b4/79/b4fbfef46aa425e1c2b1c51c6811b179.png)
图5 Session配置界面
3. 完成配置后点击Session界面的“Start Session”按钮启动iPhone模拟器并在iPhone模拟器中启动TestApp同时还会打开Inspector窗口。如图6所示。
![](https://static001.geekbang.org/resource/image/cd/d5/cd95332b27674b7986c183b967c8a9d5.png)
图6 启动Session后的Inspector窗口
4. 在Inspector窗口我们可以利用“Select Elements”功能通过点击元素显示Native App上的元素定位信息。如图7所示。
![](https://static001.geekbang.org/resource/image/31/9a/31ed3e4326ae3f3494b78b49c9f6bd9a.png)
图7 “Select Elements”功能示例
5. 在Inspector窗口可以通过“Recording”功能生成不同语言的自动化脚本。比如在启用了“Recording”功能后点击“Compute Sum”按钮就会生成如图8所示的自动化脚本片段。
![](https://static001.geekbang.org/resource/image/b2/5d/b28a1e0f1d8c9d571c675b2062ba455d.png)
图8 “Recording”功能示例
了解了如何通过Inspector获取元素定位信息的方法之后我们就来正式开发基于Appium的第一个Web App和第一个Native App的测试用例。
## 基于Appium开发你的第一个Native App的测试用例
**第一步建立一个空的Maven项目然后在POM文件中加入如图9所示的依赖。**
在这个案例里面我们会使用TestNG组织测试用例所以代码的第14行加入了TestNG的依赖。
第19行的java-client是关键java-client的作用是利用Java代码将测试用例中的操作步骤发送给Appium Server然后由Appium Server自动完成这些操作。
目前Appium支持多种编程语言每种语言都有自己的client比如这里使用Java语言所以引入了java-client如果你使用Python语言那么就需要引用python-client。
![](https://static001.geekbang.org/resource/image/09/59/0900c83c8262f90c0635626fa990f459.png)
图9 POM文件加入TestNG和java-client的依赖
**第二步创建一个类并命名为“iOS\_NativeApp\_DemoTest”然后按照如图10所示的代码实现这个class。**
注意这里的代码是真实的可执行Java代码你可以直接拿去使用。
![](https://static001.geekbang.org/resource/image/32/2e/32022f6b0166fea7498cbbdc0af9a22e.png)
图10 Native App测试用例实例
* 代码第21行的@BeforeTest第38行的@AfterTest以及第44行的@Test都是利用了TestNG的annotation对函数进行标注。
标有@Test的函数是真正的测试主体所有测试相关的步骤都放在这个函数中
标有@ BeforeTest的函数会在@Test函数之前执行测试的相关准备工作图中的代码用这个函数完成了DesiredCapabilities的设置并用该Capabilities构造了iosdriver
标有@ AfterTest的函数在@Test函数执行结束后执行主要用于环境的清理和收尾图示的代码用这个函数完成了iosdriver的退出操作。
* 代码的第24-33行构造了DesiredCapabilities对象并对APPIUM\_VERSION、PLATFORM\_VERSION、PLATFORM\_NAME、AUTOMATION\_NAME、DEVICE\_NAME和APP等参数进行了设置。其中APP的值是被测Native App安装包的绝对路径。
* 代码的第46-58行是测试用例的主体部分主要分为三部分
第47-50行通过iosdriver的findElementByAccessibilityId方法定义了页面上的四个元素分别是输入参数框A、输入参数框B、计算按钮和加法结果显示框。代码中具体的AccessibilityId可以通过Inspector获取。
第53-55行通过自定义元素的操作执行加法运算。
第58行通过断言方法assertEquals验证加法运算的结果。
**第三步为了运行这个TestNG的测试用例我们需要再添加一个testng.xml文件** 具体内容如图11所示。
![](https://static001.geekbang.org/resource/image/ea/0f/eadddd658205bdce9ddfa2488fe6130f.png)
图11 testng.xml文件示例
**第四步在保证Appium Server已经启动的情况下就可以运行testng.xml执行测试了。** 测试开始后首先会自动启动基于iOS 10.0的iPhone 7模拟器然后依次自动完成WebDriverAgentWDA和被测Native App的安装。
WDA是由Facebook开源的支持iOS自动化的代理工具其底层通过XCUItest实现自动化。
接着就会自动运行被测Native App并根据@Test函数中定义的步骤完成自动化测试的步骤和验证。
到此我们的第一个基于Appium的Native App自动化测试用例就设计完了。
## 基于Appium开发你的第一个Web App的测试用例
有了Native App测试用例的设计基础再来实现一个基于Appium的Web App自动化测试用例就简单得多了。
**第一步在上述的Maven项目中再创建一个类并命名为“iOS\_WebApp\_DemoTest”然后按照如图12所示的代码实现这个类。**
![](https://static001.geekbang.org/resource/image/91/16/911057393796c62e5d854607299ba216.png)
图12 Web App测试用例实例
代码的整体结构和上述Native App测试用例的完全一致只有一个地方需要特别注意代码的第29行由于Web App是基于浏览器的测试所以这里不需要指定App这个参数而是直接用BROWSER\_NAME指定浏览器的名字即可。
对于测试用例的主体部分也就是代码的第45-47行就比较简单了首先打开Safari浏览器并访问“[http://appium.io/](http://appium.io/)”接着用断言方法assertEquals验证页面的Title是不是“Appium: Mobile App Automation Made Awesome.”。其中实际页面的Title可以通过mobiledriver的getTitle方法获得。
**第二步在testng.xml中添加这个Web App的测试用例然后我们就可以在Appium Server已经启动的情况下执行这个测试用例了。**
这个测试用例首先会自动启动基于iOS 10.0的iPhone 7模拟器然后自动打开Safari浏览器并访问Appium的官方网站。执行完成后的界面如下图13所示。
![](https://static001.geekbang.org/resource/image/7a/9c/7ada743125c6412e20b0b944b479559c.png)
图13 测试用例执行完成的界面
进行到这里我们基于Appium开发的第一个Web App的自动化测试用例也就开发完成了。
经过前面Appium环境搭建以及两个测试用例的设计相信你已经对Appium有了一个感性的认识了。那么Appium的实现原理又是怎样的呢理解了Appium的使用原理可以帮助你更好地使用这个工具设计更加“有的放矢”的测试用例。
## Appium的实现原理
Appium作为目前主流的移动应用自动化测试框架具有极强的灵活性主要体现在以下5个方面
* 测试用例的实现支持多种编程语言比如Java、Ruby、Python等
* Appium Server支持多平台既有基于Mac的版本也有基于Windows的版本
* 支持Web App、Native App和Hybird App三大类移动应用的测试
* 既支持iOS也支持Android
* 既支持真机,也支持模拟器。
实际应用中你可以根据项目情况灵活组合完成移动应用的自动化测试。比如用Java写iOS上的Native App的测试用例测试用例跑在Mac平台的iPhone虚拟机上或者用Python写Android上的Web App的测试用例测试用例通过Windows平台跑在Android的真机上。
这样的组合还有很多很多。那你有没有想过Appium为什么可以做到如此强大的灵活性呢这就要从Appium的基本原理讲起了。
要真正理解Appium的内部原理你可以把Appium分成三大部分分别是Appium Client、Appium Server和设备端。这三部分的关系如图14所示。
![](https://static001.geekbang.org/resource/image/97/ef/97a2e84f7766d8ee38eb3923b4b9d8ef.png)
图14 Appium内部原理
**我们先来看看处于中间位置的Appium Server。**
Appium Server有Mac和Windows版本也就是说Appium Server可以运行在Mac或者Windows电脑上。本质上Appium Server是一个 Node.js 应用接受来自Appium Client的请求解析后通过WebDriver协议和设备端上的代理打交道。
* 如果是iOSAppium Server会把操作请求发送给WebDriverAgent简称WDA然后WDA再基于XCUITest完成iOS模拟器或者真机上的自动化操作
* 如果是AndroidAppium Server会把操作请求发送给appium-UIautomator2-server然后appium-UIautomator2-server再基于UIAutomator V2完成Android模拟器或者真机上的自动化操作。
Appium Client其实就是测试代码使用对应语言的Client将基于JSON Wire协议的操作指令发给Appium Server。
整体来说Appium的内部原理可以总结为**Appium属于C/S架构Appium Client通过多语言支持的第三方库向Appium Server发起请求基于Node.js的Appium Server会接受Appium Client发来的请求接着和iOS或者Android平台上的代理工具打交道代理工具在运行过程中不断接收请求并根据 WebDriver 协议解析出要执行的操作最后调用iOS或者Android平台上的原生测试框架完成测试。**
## 总结
好了,我来总结一下今天的主要的内容:
目前网络上Appium工具使用相关的资料都比较零散为此我以最新版本的Appium Desktop 1.6.2和Appium Server 1.8.1为例手把手地带你搭建了iOS环境以及Appium测试环境并介绍了如何通过Appium Inspector来定位页面元素。
搭建好了测试环境后我分别针对Native App和Web App这两类移动应用基于Appium实现了两个测试用例这也是我在这个专栏里面为你实现的第一个移动应用的测试用例。虽然测试需求比较简单但是你也可以从中体会到移动应用测试用例设计的思想、方法。
最后本着知其然知其所以然的原则我介绍了Appium的实现原理它属于C/S架构Appium Client通过第三方库向Appium Server发起请求Appium Server接受请求然后和移动平台上的代理工具打交道代理工具在运行过程中不断接收来自Appium Server的请求并解析出要执行的操作最后调用移动平台原生的测试框架完成测试操作。
## 思考题
我在这篇文章里面举的例子都是基于iOS的建议你基于Android分别实现一个Web App和Native App的测试用例。
如果实现过程中,遇到了问题,或者有一些自己的想法,请给我留言讨论吧。