说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
关于Appium框架,早在之前的《移动端自动化测试实战(一)》系列文章中就有过介绍使用
一、Appium 简介
1.什么是 Appium
- 是一个移动端的自动化测试框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。
✔ 原生的应用是指用 android 或 ios 的 sdk 编写的应用;
✔ 移动网页应用是指网页应用,类似于 ios 中 safari 应用或者 Chrome 应用或者类浏览器的应用;
✔ 混合应用是介于 web-app 和 native-app 之间的应用。 - Appium 是模拟人的操作进行功能自动化,通常用于功能测试和兼容性测试。
2.Appium 的设计
-
第一条:采用底层驱动商提供的自动化框架。
✔ IOS
★ 苹果的 UIAutomation
✔ Android 4.2+
★ 谷歌的 UiAutomator -
第二条:采用底层驱动商提供统一 API,就是 WebDriver API。
✔ WebDriver(也称 Selenium WebDriver)其实是一个 C/S 架构的协议,叫做 JSON Wire Protocol。通过这个协议,用任何语言写成的客户端都可以发送 HTTP 请求给服务器。这就意味着可以自由选择你想要使用的测试框架和执行器,也可以将任何包含 HTTP 客户端的库文件加入到你的代码中。换句话说,Appium 的 WebDriver 不是一个技术上的测试框架,而是一个自动化库。 -
第三条:在 WebDriver 的基础上,扩展了一些适合移动端自动化协议的 API。
3.Appium 的原理
-
核心是 web 服务器
✔ 它接受客户端的连接,接收客户端的命令,在手机设备上执行命令,然后通过 HTTP 的响应收集命令执行的结果。 -
Session
✔ 自动化的过程通常在 session 上下文中执行。
✔ 客户端初始化一个 session 会话,虽然不同的语言初始化的方式不同,但是他们都要发送 POST/session 请求到服务器端,这些请求里面都会带有一个对象:desiredCapabilities,这个时候服务器端会启动自动化 session 然后返回一个 session ID,以后的命令都会用这个 seesion ID 去匹配。 -
Desired Capabilities
✔ desired capabilities 对象其实是一个 key-value 的集合,里面包含了各种各样的信息,发送到服务器端后,服务器解析这些信息就知道了客户端对哪种 session 感兴趣,然后就会启动相应的 session。
✔ 这里面的信息会影响着服务器端启动 session 的类型。比如你 platformName 的值为 ios,就是告诉服务器启动一个 ios 的 session,而不是 android seesion,之后使用 js 打开新窗口。 -
Appium Server
✔ Appium 是一个用 Node.js 编写的 HTTP server,它创建、并管理多个 WebDriver sessions 来和不同平台交互,如 iOS,Android 等。 -
Appium Clients
✔ Appium 开始一个测试后,就会在被测设备(手机)上启动一个 server ,监听来自 Appium server 的指令,每种平台(如 iOS 和 Android)都有不同的运行和交互方式,所以 Appium 会用某个桩程序“侵入”该平台,并接受指令,来完成测试用例的运行。
✔ 客户端的概念不是我们传统意义上的客户端,这里客户端更好的理解是一个扩展WebDriver 协议的库,你在用自己喜欢的语言写 case 的时候,将该语言扩展 WebDrvier 的库添加到你的环境中,你就可以理解这是个客户端。
4.Appium 的优势
- Appium 在不同平台中使用了标准的自动化 APIs,所以在跨平台时,不需要重新编译或者修改自己的应用。
- Appium 实现了真正的跨平台自动化测试。
✔ Appium 支持 Selenium WebDriver 支持的所有语言,如 java、Object-C、JavaScript、Php、Python、Ruby、C#、Perl 语言,更可以使用 Selenium WebDriver 的 Api。 Appium 支持任何一种测试框架。
二、Appium 环境搭建
1.基础环境
1.1 安装 node.js
是一个 Javascript 运行环境(runtime environment)。
1.2 安装.NET framework
软件名形如 NDP…,.net framework 是微软的开发程序的框架,用.net 开发的程序就需要.net 的环境来支持才能运行。
1.3 安装 vc_redist
- VisualC++的运行时库,包含了一些 VisualC++的库函数。
- 如果缺少,会导致 sdk 运行异常。
- 计算机中如果安装过,可以忽略此步。
1.4 安装 jdk 并配置环境变量
- 安装jdk,将jdk和jre目录改为E盘下进行安装
- 配置用户变量,编辑PATH添加JDK安装目录下的bin目录路径
- 新建用户变量CLASSPATH,添加jdk安装目录下的lib下的tools.jar文件路径
- 检验环境变量配置是否有问题,一般检查这是在cmd命令窗口输入如下命令
- 最好检测环境变量配置无误,则是编写一个java文件,进行编译执行测试
- 解决方法则是配置环境变量的值后面加上;
- 注销一下计算机,再次编译执行,成功打印
1.5 安装 android sdk
- 修改软件安装路径为e盘
- 完成安装,暂不启动
1.6 安装工具包和手机操作系统
-
安装工具包和测试所需要的操作系统
✔ system image
★ armeabi
■ 第 5 代、第 6 代 ARM 处理器,早期的手机用的比较多。
★ armeabi-v7a
■ 第 7 代 ARM 处理器。
★ arm64-v8a
■ 第 8 代 64 位 ARM 处理器。
★ x86
■ 平板、模拟器用得比较多。
■ 需要计算机是 Intel Cpu,且支持 Intel-V。
★ x86_64
■ 64 位的平板。 -
首先对虚拟机进行联网,然后打开Android SDK Manager管理器
-
安装Android4.4.2版本操作系统
-
安装
-
安装完成,出现如下提示
-
安装完成后,在管理器界面,显示之前勾选的SDK状态为installed已安装状态
-
打开Android目录,查看adb命令是否安装完成以及镜像存放目录
-
设置 Android 环境变量
✔ ANDROID_HOME:e:\android\android-sdk
✔ PATH:;%ANDROID_HOME%\platform-tools
★ adb.exe 所在目录
-
打开cmd窗口,输入adb命令,提示如下,则表示环境变量配置无误
1.7 创建模拟器
-
使用 avd manager(android virtual device)进行模拟硬件设备
✔ 选择合适的系统镜像
-
使用模拟器说明
✔ 虚拟机上运行模拟器可能导致运行缓慢
✔ 建议在真机系统行运行模拟器 -
打开 avd manager 创建模拟器
✔ 尽量选择低分辨率的“Device”
-
启动模拟器
✔ 下图中点击 Statrt,即可启动
✔ 每次执行测试前,应确保模拟器处于运行状态
✔ 过程较慢,启动完成后,可查看、可关闭
-
勾选清除用户数据,启动
-
模拟器启动过程比较忙,毕竟博主是在虚拟机中进行启动
1.8 安装 Appium
- 进行后续测试之前必须启动 Appium。
- appium 下载地址
✔ https://github.com/appium/appium-desktop/releases/
- 安装完成,启动Appium
- 打开Appium后,点击启动如果不报错则说明,安装没有任何问题,此时的Android模拟器已经开机成功了(说明一下,因为是在虚拟机进行操作演示,所以appium及Android操作系统都是低版本的,在博主之前写的移动端自动化测试实战文章中是以本机进行演示的所以都是高版本的)
- 启动appium后,日志没有显示错误
- 最大化appium窗口,点击右下角的删除按钮,可以清楚日志
2.Java+Appium 环境
-
在基础环境上继续安装。
-
eclipse 构建路径,导入如下包入库(注意版本需要匹配)
✔ java-client-*.jar
★ 下载地址
■ https://mvnrepository.com/artifact/io.appium/java-client
✔ selenium-server-standalone-*.jar
✔ testng-6.14.zip
★ TestNG 是一个开源自动化测试框架,TestNG 表示下一代。
★ 用于设置测试前的准备代码,测试代码,测试完毕后的处理代码。
★ 离线安装。 -
装好eclipse,点击帮助——安装新软件
-
安装testng
-
勾选挂载出来的testng压缩包,点击下一步
-
完成安装
-
新建项目,在项目上配置构建路径
-
添加外部jar包
三、使用 Java 语言编写测试脚本
1.创建测试类
- 右击test包,新建其他
- 找到TestNG下的类
- 创建一个TestNG类,并勾选创建注解方法
- 定义 AppiumDriver 对象
2.@BeforeClass 注解
- 用于设定进入测试类后,在所有测试之前首先要执行的代码
2.1 创建DesiredCapabilities对象
- 创建 DesiredCapabilities 对象
2.2 指定测试设备平台
- 指定测试设备平台
✔ device.setCapability(“deviceName”,“Android Emulator”);
★ 使用的移动设备或模拟器的种类,如 iPhone Simulator,iPad Simulator, Android Emulator,Galaxy S4 等✔ device.setCapability(“platformName”,“Android”);
★ 指定使用哪个移动操作系统平台,如 iOS,Android 或 FirefoxOS
✔ device.setCapability(“platformVersion”,“4.4.2”);
★ 指定移动操作系统版本
2.3 指定app程序包名
-
指定 app 程序包名,即被测程序名
✔ 如 device.setCapability(“appPackage”,“com.android.calculator2”);
✔ 如何探测程序名
★ 打开并进入软件
★ 通过\Android\android-sdk\tools\uiautomatorviewer.bat 去探测,package 后面的文字即程序名。
★ 若 cmd 窗口下出现 Unable to detect adb version 错误
■ 检查 path 环境变量:PATH:;%ANDROID_HOME%\platform-tools -
首先在Android模拟器中打开计算机(被测程序),然后运行uiautomatorviewer.bat文件
-
点击如下按钮,可以对在Android模拟器打开的计算器,进行截图探测
-
默认鼠标移动(块为虚线),可以根据鼠标的移动查看坐标及元素数据,鼠标左键点击则变成锁定(块为实线),package后面则为程序名
-
复制程序名,在代码中进行指定
2.4 指定app启动项名称
-
指定 app 启动项名称
✔ device.setCapability(“appActivity”,".Calculator");
✔ 启动项的名字,类似于窗口名。
★ 打开 APP→执行 adb logcat>D:/log.txt → 胡乱的对 APP 做一些操作→ Ctrl+C 结束 adb 命令→打开 log.txt 文件,搜索:Displayed,“/”左边的是包名,右边是 Activity。 -
首先在UI Automator Viewer无法查看打开程序的名称,所以需要在cmd窗口通过adb命令生成操作程序日志中去查找(在移动端自动化测试实战中是另一种方式)
-
紧接着,ctrl+c停止命令,打开生成的a.txt文本,搜索displayed关键字,会出现多个匹配项,要找的是带有包名的display项,在包名的后面则是启动项名.Calculator
-
回到eclipse中指定启动项名,不要忘记.
2.5 启动 App
- driver = new AndroidDriver(new URL(“http://localhost:4723/wd/hub”),device);
✔ wd 是 WebDriver 的缩写
✔ hub 指主(中心)节点,selenium 分布式里的中心节点
3.运行测试
- 运行方式→TestNG Test
✔ 注意启动 Appium。
✔ 测试方法需要加@Test 才能运行。
- 运行测试之前,需保证appium是启动状态,运行测试成功打开计算器(不过是真的慢,真的卡)
- 查看日志显示通过
- 查看appium日志,没有error错误日志(要不是博主的本机电脑装的程序太多,真不想在虚拟机中进行app测试,实在是太慢太卡了)
4.@AfterClass 注解
- 在所有测试之后再执行的代码。
✔ 退出 App
★ driver.quit()
5.@Test(属性=值)注解
- 指定要测试的方法,方法名只要符合标识符命名规则。
- 属性
✔ description=“测试描述”
✔ priority=优先级,从 0 开始
✔ timeout=?ms,超时时间
✔ dataProvider=“Dataprovider 的名称或方法名”
✔ dataProviderClass=产生测试数据的类
6.识别与操作控件元素
- driver.findElementById(resource-id 属性)
- driver.findElementByClassName(class 属性)
- driver.findElementBy?(属性).sendKeys(“数据”)
- driver.findElementBy?(属性).clear()
- driver.findElementBy?(属性).click()
- driver.findElementBy?(属性).getText()
6.1 案例1:操作计算器完成加法运算
- 首先通过UI Automator View来获取计算机上按键元素属性
- 通过以上方法完成92+8的加法运算所需按键的元素id属性,然后在eclipse中编写如下代码
- 运行代码,成功完成92+8加法运算,测试通过
- 如果想要在控制台打印出计算后的结果数据,那么首先通过UI Automator View来获取到结果文本框的属性
- 然后在代码中通过classname来定位结果文本框,然后获取该元素的文本数据即可
- 对每次执行完命令后,对结果文本数据进行清空处理,首先定位清空键属性
- 在脚本中编写如下
7.断言
7.1 Assert.assertTrue(boolean 型结果)
- 写法类似于正则表达式,使用更方便。
- Boolean rs=driver.findElementById(…).getText().contains( );
- Assert.assertTrue(rs);
- 运行脚本,测试通过,说明断言成功
7.2 Assert.assertEquals(实际结果,预期结果)
-
用于测试期望结果的断言,即测试两个对象是否相等。
-
String actual=实际结果;
-
String expected=预期结果;
-
Assert.assertEquals(actual, expected);
✔ String res=driver.findElementByClassName(“android.widget.EditText”).getText();
✔ Assert.assertEquals(res,“3”); -
优化代码,如果每次点击几位数,都需要重复定位元素并进行点击操作,所以可以通过for循环遍历字符串的长度来获取具体数字来进行点击操作,这样就可以少些很多重复代码
-
运行脚本,查看控制台打印结果没有任何问题
-
现在在脚本中设置预期结果和实际结果,并通过assertEquals方法判断两个值是否相等