精通移动App测试实战:技术、工具和案例

       本文是根据书籍《精通移动App测试实战:技术、工具和案例》进行学习记录,方便后期查阅,感谢书籍作者提供的学习机会。

目录

第1章 Android系统基础内容介绍

1.6创建模拟器

第2章JUnit框架基础

2.1Junit框架介绍

2.2Junit在Android开发中的应用

第3章 ADB命令

3.1Android调试桥介绍

3.2ADB相关指令实例讲解

3.3手机模拟器相关的一些操作命令实例详解

3.3.1模拟器上模拟手机来电命令实例详解

3.3.2模拟器上模拟发送短信命令实例讲解

3.3.3模拟器上模拟网络相关命令实例讲解

3.3.4修改模拟器的大小比例相关命令实例讲解

3.3.5模拟器的其它命令及如何退出模拟器控制台

3.4 模拟器相关命令实例详解

3.5创建安卓虚拟设备命令实例讲解

3.6 创建安卓项目相关命令实例讲解

第4章 Monkey工具使用       

4.1工具简介

4.2Monkey演示实例

4.2.1第一个Monkey示例(针对日历应用程序)

4.2.2如何查看Monkey执行过程信息

4.2.3如何保持设定各类事件执行比例     

4.3Monkey相关参数讲解

4.4Monkey相关命令介绍

4.5Monkey如何执行脚本

第5章 MonkeyRunner工具使用

5.1MonkeyRunner工具简介

5.2MonkeyRunner安装部署

5.3MonkeyRunner演示示例

5.4MonkeyRunner脚本手工编写

5.5MonkeyRunner样例脚本

第6章 Robotium 自动化测试框架

6.1Robotium 自动化测试框架简介

6.2Robotium环境搭建

6.3第一个Robotium示例(针对记事本应用程序)

6.4用Robotium实现对APK或有源码的项目实施测试

6.5用Robotium Recorder录制脚本

6.6Robotium获取控件的方法

6.7测试用例脚本的批量运行

6.8持续集成

第7章 自动化测试工具-UI Automator

7.1为什么选择UI Automator

7.2UI Automator演示示例

7.3 UI Automator 

7.4 UI Automator常见问题解答

第8章 自动化测试工具—Appium实战

8.1为什么选择Appium

8.2 Appium环境部署

8.3 Appium元素定位的3个利器

8.4多种界面控件的定位方法介绍

8.5 多种界面控件的操作方法介绍

8.6捕获异常、创建快照

第9章 移动平台性能测试

9.1 移动平台性能测试简介

9.2移动端性能测试工具

9.3 LoadRunner


第1章 Android系统基础内容介绍

精通移动App测试实战:技术、工具和案例_第1张图片

1.6创建模拟器

  1. 关于模拟器使用:
  1. 模拟器在没有物理手机设备时对调试测试脚本程序非常有帮助
  2. 模拟器的执行效率要比同配置的真实手机设备低
  3. 模拟器因为相关的参数可配置,所以可以模拟操作系统版本的升级情况
  4. 模拟器因为相关的参数可配置,所以建议大家执行测试脚本用例时可以在低版本的系统测试其兼容性
  5. 模拟器和真实的物理设备还是有差别的,建议在做实际的自动化测试时还是要用真实的物理设备。

第2章JUnit框架基础

2.1Junit框架介绍

  1. 对于经常变化的项目而言敏捷开发适用性优于瀑布模型。
  2. XUnit系列的工具包括Junit(针对Java)、DUnit(针对Delphi)、NUnit(针对.Net)和PythonUnit(针对Python)等

2.2Junit在Android开发中的应用

精通移动App测试实战:技术、工具和案例_第2张图片

1、JUnit4常用的几个Annotation介绍:

(1)@Before:初始化方法

(2)@After:释放资源

(3)@Test:测试方法,在这里可以测试一些测试用例,正常的、异常的测试用例

(4)@Ignore:忽略的测试方法

(5)@BeforeClass:针对所有测试,只执行一次,且必须为static void;

(6)@AfterClass:针对所有测试,只执行一次,且必须为static void;

2、断言:JUnit为我们提供了一些辅助函数,用来帮助我们确定被测试的方法是否按照预期的效果正常工作,通常把这些辅助函数称为断言。

第3章 ADB命令

3.1Android调试桥介绍

  1. ADB是Android提供的客户端/服务器架构的通用调试工具,主要由adb客户端、adb服务器、adb daemon(守护进程)3部分组成
  2. 任何模拟器或设备实例会取得两个连接端口,一个偶数端口用来控制与控制台的连接,一个基数端口用来控制与adb的连接。

 

3.2ADB相关指令实例讲解

1、adb devices了解物理测试设备或模拟器相关信息

  1. device状态:表示设备或模拟器已连接到adb服务器上,但并不代表设备或模拟器已经启动完毕可以操作,因Android系统启动时会先连接到adb服务器上,但Android系统启动完毕后,设备或者模拟器通常是这个状态。
  2. Offline状态:表明设备或模拟器没有连接到adb服务器或没有反应
  3. On device状态:表明没有物理设备或模拟器连接。       

2、adb install

精通移动App测试实战:技术、工具和案例_第3张图片

(1)Android MM 模拟器设备安装

adb -s emulator-5554 install C:\Users\Administrator\Desktop\MMyingyongshangchang_10641.apk

(2)如果已安装应用,又不想卸载后再安装

adb -s emulator-5554 install  -r C:\Users\Administrator\Desktop\MMyingyongshangchang_10641.apk

(3)若只连接了一个物理手机设备或者一个模拟器设备

adb  install  C:\Users\Administrator\Desktop\MMyingyongshangchang_10641.apk

 

3、adb uninstall指令实例讲解

APP卸载方法:

  1. 方法一:通过物理手机或模拟器设备自带的卸载功能进行卸载
  2. 方法二:应用PC上安装的一些手机助手类工具软件来卸载
  3. 方法三:应用手机或者模拟器设备上安装的一些工具软件来卸载应用
  4. 方法四:应用adb uninstall命令卸载手机应用

 

4、adb pull指令实例讲解 手机端下载文件到电脑

5、adb push 指令实例讲解 将电脑上的文件传送到物理手机设备或模拟器。不仅能够传送文件,也能够传送文件夹到手机或者模拟器设备

6、Adb shell指令实例讲解

Adb shell +相关指令及其参数 来执行这些指令

例如:adb shell ls查看手机当前目录所有内容

adb shell、su  root(切换为root用户)、cd /data/data、ls

7、adb shell dumpsys battery指令实例详解 查看电池电量的相关信息

8、adb shell dumpsys WiFi 查看无线网络信息

9、adb shell dumpsys power 查看电源管理相关信息

10、adb shell dumpsys telephony.registry 查看电话相关信息

11、adb shell cat /proc/cpuinfo 查看CPU硬件相关信息

“/proc”区分保存的系统各种实时信息,如CPU、内存等信息

12、adb shell cat /proc/meminfo 查看内存相关信息

13、adb shell cat /proc/iomem 查看内存分区的相关信息

14、adb shell cat /system/build.prop|findstr “ro.product.model”获取手机型号

模拟器输出:

15、adb shell cat /proc/cpuinfo|findstr “Processor” 获取手机处理器信息

16、adb shell cat /proc/meminfo|findstr “MemTotal”获取手机内存信息

17、adb shell dumpsys window|findstr “Display” 获取手机屏幕分辨率的相关信息

18、adb shell getprop ro.build.version.release 获取手机系统版本相关信息

19、adb shell cat /proc/version 获取手机内核版本信息

20、adb shell getprop gsm.operator.alpha 获取手机运营商信息

21、adb shell getprop gsm.network.type 获取手机网络类型相关信息

22、adb shell dumpsys iphonesubinfo|findstr “Device ID” 获取手机串号信息

23、adb shell df 获取手机Android系统各个分区相关信息

精通移动App测试实战:技术、工具和案例_第4张图片

24、adb shell dmesg 输出Linux内核的环形缓冲区信息,从中获得诸如系统架构、CPU、挂载硬件、RAM等多个运行级别大量的系统信息

25、adb shell dumpstate 获取手机Android系统当前状态的相关信息

26、adb get-serialno获取设备序列号

27、adb get-state 查看模拟器/设备的当前状态(分为device/offline/no device)

28、adb logcat 查看和跟踪系统日志缓冲区的信息

29、adb bugreport 查看Android启动过程的日志信息以及启动后的系统状态

30、adb jdwp列出指定设备的JDWP(Java调试器无线协议)相关的进程ID

31、adb start-server 用于启动adb服务

32、adb kill-server 用于关闭adb服务

33、adb forward将本机端口重定向到模拟器或设备接口上

34、am 全称 Activity Manager模拟各种系统行为

35、pm指令全称package manager,用于模拟Android行为或者查询设备上的应用

adb shell pm list packages

3.3手机模拟器相关的一些操作命令实例详解

3.3.1模拟器上模拟手机来电命令实例详解

1、模拟器是如何工作的?

  1. 模拟器启动之后会打开一个网络嵌套字(Socket)端口与其所在的主机通信
  2. 借助Telnet操控模拟器,通过端口(5554)与模拟器进行交互
  3. Telnet localhost 5554

    4.gsm call

遇到Android授权问题:auth

精通移动App测试实战:技术、工具和案例_第5张图片

精通移动App测试实战:技术、工具和案例_第6张图片精通移动App测试实战:技术、工具和案例_第7张图片

3.3.2模拟器上模拟发送短信命令实例讲解

sms send hi tester

精通移动App测试实战:技术、工具和案例_第8张图片

3.3.3模拟器上模拟网络相关命令实例讲解

  1. network status:查看网络状态信息
  2. Network speed:设定模拟器网速
  3. Network delay:设定模拟器的网络延时
  4. Network capture start/stop:捕获模拟器的网络数据包

3.3.4修改模拟器的大小比例相关命令实例讲解

Window scale 0.5 将模拟器尺寸变为原尺寸的一半

3.3.5模拟器的其它命令及如何退出模拟器控制台

Help Power命令查看相关帮助信息

精通移动App测试实战:技术、工具和案例_第9张图片

 

3.4 模拟器相关命令实例详解

 

1、了解模拟器的Android系统版本:Android list targets

精通移动App测试实战:技术、工具和案例_第10张图片

3.5创建安卓虚拟设备命令实例讲解

  1. Android create avd --name android4.4.2 --target 2 --abi armeabi-v7a

其中:--name为创建的手机模拟器名称、--target为“Android list targets”命令查询到的标示号、--abi后为应用二进制接口的类型

精通移动App测试实战:技术、工具和案例_第11张图片

模拟器屏幕密度240、物理内存512M、虚拟内存48M

  1. 重命名模拟器命令实例讲解
  2. 查看模拟器命令实例讲解 Android list avd
  3. 删除模拟器命令实例讲解 Android delete avd -n
  4. 启动模拟器命令实例讲解 emulator -avd android4.4.2

 

3.6 创建安卓项目相关命令实例讲解

1、切换到myeclipse项目的工作目录

2、创建测试项目:

android create test-project -m D:\MyEclipse 2015 CI\NotePad -p D:\MyEclipse 2015 CI\NotePadTest

android create test-project -m D:\MyEclipse 2015 CI\LawControl -p D:\MyEclipse 2015 CI\LawControlTest

3、基于控制台命令行相关命令使用指导

  1. Android --help或Android -h
  2. android move avd -h

第4章 Monkey工具使用       

4.1工具简介

Monkey测试是一种测试软件稳定性、健壮性的快速有效的方法。

4.2Monkey演示实例

4.2.1第一个Monkey示例(针对日历应用程序)

  1. 启动模拟器后 cmd中输入 adb shell monkey
  2. Adb shell  su root  cd data  cd data  ls
  3. adb shell monkey -p com.android.calendar 1000

精通移动App测试实战:技术、工具和案例_第12张图片

 

4.2.2如何查看Monkey执行过程信息

包含1个-v参数时,信息的详细级别就为0级

包含2个-v参数时,信息的详细级别就为1级

包含3个-v参数时,信息的详细级别就为2级

1、0级时,adb shell monkey -v-p com.android.calendar 100

2、1级时,adb shell monkey -v-v-p com.android.calendar 100

3、2级时,adb shell monkey -v-v-v-p com.android.calendar 100

针对打印输出内容分析:

(1):Monkey:seed=0 count=100

未指定随机种子-s参数时,默认使用是0 count是100命令中已经指定

(2):AllowPackage:com.android.calendar

含义是只启动在com.android.calendar包中的Activity(活动)

4.2.3如何保持设定各类事件执行比例     

 

  精通移动App测试实战:技术、工具和案例_第13张图片

精通移动App测试实战:技术、工具和案例_第14张图片

4.3Monkey相关参数讲解

1、-s参数的示例讲解

Monkey提供的-s参数,用于指定伪随机数生成器的seed(种子)值,如果seed值相同,则两次Monkey测试所产生的事件序列也相同。

  1. 重现问题是测试人员经常面对的一件事情, 因此-s参数的使用尤为重要,建议测试时,记录每次使用的命令及用管道命令保存输出结果到文件中,使得命令和执行结果一一对应
  2. adb shell monkey -v-v-v-p com.android.calendar 100 > C:\calendar.txt

输出Monkey的执行结果信息到alendar.txt

2、-p参数的示例讲解

-p参数用于约束限制,用此参数指定一个或多个包(package,APP)。指定包之后,Monkey只将允许系统启动用户指定的APP。不指定时随机启动系统中的任意APP

不指定包:Adb shell monkey 100

指定单个包:Adb shell monkey -p com.android.calendar 100

指定两个或多个包:Adb shell monkey -p com.android.calendar -p com.tencent.news 100

3、--throttle参数的示例讲解

--throttle用于指定各操作也就是随机事件间的延时

Adb shell monkey -p com.android.calendar --throttle 3000 100 向日历应用发送100次随机事件,每次事件间隔为3秒

4、--pct-touch参数的示例讲解                                                         

用于设定触屏事件生成的百分比

adb shell monkey --pct-touch 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔为3秒,其中设定触屏的时间占比为50%              

5、--pct-motion参数的示例讲解

用于设定滑动时间生成的百分比,滑动事件是先在某一个位置手指按下,滑动一段距离后再抬起手指的手势

Adb shell monkey --pct-motion 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔3秒,其中设定滑动的事件占比为50%

6、--pct-trackball参数的示例讲解

用于设定轨迹球事件生成的百分比,轨迹球事件是包含一系列随机移动和单击事件的事件

Adb shell monkey --pct-trackball 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔3秒,其中设定轨迹球事件的占比为50%

7、--pct-nav参数的示例讲解

用于设定基本的导航事件的百分比,基本导航事件是模拟方向性设备输入向上、向下、向左、向右的事件

Adb shell monkey --pct-nav 50 -p com.android.calendar--throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔3秒,其中设定导航事件占比50%

8、--pct-majornav 参数示例讲解

用于设定主要导航事件的百分比,主要导航事件通常会导致UI产生回馈事件,如单击BACK键、Menu键

Adb shell monkey --pct-majornav 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔为3秒,其中设定主要导航事件占比为50%

9、--pct-syskeys参数的示例讲解

用于设定系统案件事件的百分比,系统按键通常被保留,由系统使用,如Home、back、拨号、挂断及音量控制键

Adb shell monkey --pct-syskeys 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔为3秒,其中设定主要Home、back、拨号、挂断及音量控制事件占比50%

10、--pct-appswitch参数的示例讲解

用于设定启动活动事件的百分比,在随机的一定间隔后,Monkey就会执行一个startActivity()函数尽可能多的覆盖包中全部活动

Adb shell monkey --pct-appswitch 50 -p com.android.calendar--throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔为3秒,其中设定主要覆盖包中50%的活动(Activity)

11、--pct-anyevent参数的示例讲解

用于设定其他类型事件的百分比,如普通按键消息、不常用的设备按钮事件等

Adb shell monkey --pct-anyevent 50 -p com.android.calendar --throttle 3000 100

向日历应用发送100次随机事件,每次事件间隔3秒,其中普通按键消息、不常用的设备按钮事件占50%

12、--hprof参数的示例讲解

指定改参数后Monkey会在发生事件序列的前、后,生成性能分析报告。通常会在data/misc目录下生成一个5M左右大小的文件

13、--ignore-crashes参数的示例讲解

通常情况下、Monkey会在待测应用程序崩溃或发生任何异常后停止运行。若指定了该参数,则Monkey将会在产生异常后,继续向系统发送事件,直到指定的事件消息全部完成为止。

Adb shell monkey -p com.android.calendar --ignore-crashes 100

向日历应用发送100次随机事件,测试过程中即使日历应用程序崩溃,Monkey依然会继续发送事件直到事件数目达到100为止

Adb shell monkey -p com.android.calendar 100

向日历应用发送100次随机事件,测试过程中如果日历应用程序崩溃,Monkey测试就会中断,停止运行

14、--ignore--timeouts 参数的示例讲解

通常情况下,当应用程序发生任何超时错误时,Monkey将停止运行,若指定了该参数,则Monkey将会在产生错误信息后继续向系统发送事件,直到事件消息全部完成为止

Adb shell monkey -p com.android.calendar --ignore-timesout 100

向日历应用发送100次随机事件,测试过程中即使出现ANR错误,Monkey依然会继续发送事件直到事件数目达到100为止

15、--ignore-security-exceptions参数的示例讲解

通常情况下用于指定应用程序发生许可错误(如证书许可、网络许可等)Monkey是否停止运行,如果使用此参数,即使应用程序发生许可错误,Monkey依然会发送事件,直到指定的事件消息全部完成为止

Adb shell monkey -p com.android.calendar --ignore-security-exceptions 100

向日历事件发送100次随机事件,测试过程中即使出现证书许可错误或网络许可错误等,Monkey依然会继续发送事件直到事件数目达到100为止。

16、--kill-process-after-error参数的示例讲解

通常情况下,当Monkey由于一个错误而停止时,出错的应用程序将继续处于运行状态,当设置了此选项时,它将会通知系统停止发生错误的进程

注意:当Monkey正常执行完毕后,它不会关闭所启动的应用,设备依然保留其最后收到的消息状态,所以建议用户在执行命令以后为保持应用的初始状态,需手动或者脚本程序将已打开的应用进行关闭

17、--monitor-native-crashes 参数的示例讲解

监视并报告Android系统中本地代码的崩溃事件,如果设置了--kill-process-after-error,系统将停止运行

18、--wait-dbg参数的示例讲解

启动Monkey后,先中断其运行,等待调试器和它相连接

19、Monkey综合示例

Adb shell monkey --ignore-crashes --ignore-timeouts --kill-process-after-error --ignore-security-exceptions --throttle 1000 -v-v-v-s 5 1000000

向系统发送1000000次随机事件,各个随机事件的时间间隔为1秒钟,它的种子是5,测试过程中忽略相关的安全、超时、崩溃等异常。

4.4Monkey相关命令介绍

1、DispatchPointer命令介绍

命令说明:用于向一个坐标点(x,y)发送手势信息

命令原型: DispatchPointer(long downTime,long eventTime,int action,float x,float y,float pressure,float size,int metaState,float xPrecision,float yPrecision,int device,int edgeFlags);

参数介绍:

downTime:表示键最初被按下的时间,该值只要一个合法的长整型就可以

eventTime:表示事件发生的时间,该值只要一个合法的长整型就可以

Action:表示发送消息的类型,0(按下),1(抬起),2(移动)

X:x轴坐标

Y:y轴坐标

Pressure:表示当前事件的压力,范围0-1,压力的范围一般从0(根本没有压力)到1(正常压力)

Size:表示触摸的近似值,范围0-1

metaState:表示当前按下的meta键的标识,meta键指的是ALT、SHIFT、CAPS_LOCK

xPrecision:表示X坐标精确值

yPrecision:表示Y坐标精确值

Device:表示事件来源

edgeFlags:表示边缘的指示,如果有的话,在该位置会触发移位事件

 

2、DispatchTrackball命令介绍

命令说明:用于向一个坐标点发送跟踪球消息

命令原型:DispatchTrackball(long downTime,long eventTime,int action,float x,float y,float pressure,float size,int metaState,float xPrecision,float yPrecision,int device,int edgeFlags)

 

3、DispatchKey命令介绍

命令说明:用于发送按键消息给指定设备或者模拟器

命令原型:DispatchKey(long downTime,long eventTime,int action,int code,int repeat,int metaState,int device,int scancode)code代表按键的值,repeat代表按键的重复次数

 

4、DispatchFlip命令介绍

命令说明:用于打开或关闭软键盘

命令原型:DispatchFlip(boolean keyboardOpen)

参数原型:当keyboardOpen为true时表示打开软键盘,而为false时表示关闭软键盘

 

5、LauchActivity命令介绍

命令说明:用于启用任意引用的一个活动界面

命令原型:LaunchActivity(String pkg_name,String cl_name)

参数介绍:pkg_name要启动的应用包名, cl_name要启动的活动名称

 

6、LaunchInstrumentation命令介绍

命令说明:用于运行一个仪表盘测试用例

命令原型:LauchInstrumentation(test_name,runner_name)

参数介绍:test_name为要运行的测试用例名,runner_name为运行测试用例的类名

 

7、UserWait命令介绍

命令说明:用于让脚本中断一段时间

命令原型:UserWait(long sleeptime)

参数介绍:sleeptime为毫秒

8、RunCmd命令介绍

命令说明:用于在设备上运行Shell命令

命令原型:RunCmd(cmd)

参数介绍:cmd为要执行的Shell命令

 

9、Tap命令介绍

命令说明:该命令用于模拟一次手指单击事件

命令原型:Tap(x,y,tapDuration)

参数介绍:x,y为坐标点的横纵坐标值,tapDuration为可选项,表示单击的持续时间

 

10、ProfileWait命令介绍

命令说明:用于等待5秒

命令原型:ProfileWait()

参数原型:无

 

11、DeviceWakeUp命令介绍

命令说明:用于唤醒设备并解锁

命令原型:DeviceWakeUp()

参数原型:无

 

12、DispatchString命令介绍

命令说明:用于向Shell输入一个字符串

命令原型:DispatchString(input)

参数原型:input为要输入的字符串

 

4.5Monkey如何执行脚本

第5章 MonkeyRunner工具使用

5.1MonkeyRunner工具简介

  1. 由Google开发,用于Android系统的自动化测试工具,Android系统自带,存在于Android SDK中
  2. MonkeyRunner提供了一套API,用此API写出的程序可以在Android代码之外控制Android设备和模拟器
  3. 通过MonkeyRunner可以写出一个Python程序去安装一个Android程序,也可以运行它,向其发送一些模拟按键、滑屏、输入字符、截屏保存图片等操作
  4. MonkeyRunner和Monkey的区别?

(1)Monkey工具主要是直接运行在设备或模拟器的adbshell中,生成用户或系统的伪随机事件流,虽支持一些命令用于控制按键、滑屏等操作指令,但是支持的命令语句有限,面对逻辑控制的情况没有办法控制逻辑关系

(2)MonkeyRunner工具采用的C/S架构,运行在PC端,逐行解释Jython脚本代码,将其命令发送到Android设备或模拟器,MonkeyRunner基于Jython,而Jython又为Python和Java语言之间提供了互操作的桥梁,这样就扩展了MonkeyRunner,使其功能更加强大,可通过手工编写MonkeyRunner脚本,也可通过monkey_recorder.py脚本启动录制功能来产生脚本

 

5.2MonkeyRunner安装部署

1、运行monkeyRunner.bat文件

精通移动App测试实战:技术、工具和案例_第15张图片

2、安装Python

精通移动App测试实战:技术、工具和案例_第16张图片

5.3MonkeyRunner演示示例

1、第一个MonkeyRunner演示示例(针对微信)

精通移动App测试实战:技术、工具和案例_第17张图片

2、如何利用monkey_recorder.py进行脚本录制

#!/usr/bin/env monkeyrunner
# Copyright 2010, The Android Open Source Project#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at#
# http://www.apache.org/licenses/LICENSE-2.0#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from com.android.monkeyrunner import MonkeyRunner as mr
from com.android.monkeyrunner.recorder import MonkeyRecorder as recorder
device = mr.waitForConnection()
recorder.start(device)

精通移动App测试实战:技术、工具和案例_第18张图片

 

 

3、如何利用monkey_playback.py进行脚本回放

 

4、如何利用monkeyhelp.html文件获取读者想要的

monkeyhelp.html文件包含了MonkeyRunner提供的API接口相关信息,通过单击要了解的API接口名称了解其实现功能、包含参数、每个参数的含义及其返回值等信息内容。

 

5.4MonkeyRunner脚本手工编写

1、MonkeyRunner关键类介绍

  1. MonkeyRunner:为MonkeyRunner程序提供工具方法的列。提供了用于连接MonkeyRunner到设备或模拟器的方法,同时还提供了用于创建一个MonkeyRunner程序的用户界面以及显示内置帮助的方法。
  2. MonkeyDevice:是一个设备或模拟器的类。提供了安装和卸载程序包、启动一个活动(Activity)以及发送键盘或触摸事件到应用程序的方法,同时也可以用这个类来运行测试包
  3. MonkeyImage:是一个截图对象的类。这个类提供了截图、将位图转换成各种格式、比较两个MonkeyImage对象以及写图像到文件的方法。

 

2、MonkeyRunner脚本编写

举例SimpleApp.apk的安装、运行,进行截屏保存至D盘根目录,文件名称为“simp.png”,可通过查看“simp.png”的显示效果来验证安装过程及其打开应用的正确性

可供选择的实现方案有:利用Eclipse、运行命令控制台输入monkeyrunner,在提示符下直接输入脚本语句或者编写一个Python脚本,然后通过运用monkeyrunner运行相关的脚本,以下介绍最常用的编写Python脚本的方法,脚本分析如下:

  • from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

引入了3个关键类

  • device = MonkeyRuner.waitForConnection()

无参数时无限等待设备连接,如device = MonkeyRuner.waitForConnection(5,’b4726a2d’),第一个参数是等待连接的时间,第二个是指定要连接的设备序列号(设备序列号的获取“adb devices”)

  • device.installPackage(“f:\\SimpleApp.apk”)

进行SimpleApp.apk应用包安装

  • MonkeyRunner.sleep(3)

等待3秒

  • device.shell(‘am force-stop simple.app.SimpleAppActivity’)

为了防止“simple.app.SimpleAppActivity”已经被打开,强制关闭着Activity,如果没被打开也无所谓

  • MonkeyRunner.sleep(3)

有执行一个3秒等待

  • device.startActivity(component=’simple.app/simple.app.SimpleAppActivity’)

启动“SimpleAppActivity”

  • device.drag((288,204),(288,1024),3,1)

因手机仍处于锁屏状态,必须滑动屏幕

  • MonkeyRunner.sleep(3)

然后又等待了3秒

  • result = device.takeSnapshot()

    result.writeToFile(‘d:\\simp.png’,’png’)

手机屏幕的截屏操作,并将信息保存到d:\simp.png文件

 

以百度云APP为例

(1)找到APP的包和activity

(2)test.mr文件

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage
device = MonkeyRunner.waitForConnection()
device.installPackage('D:\weixin_1260.apk')
MonkeyRunner.sleep(3)
device.shell('am force-stop com.tencent.mm.ui.LauncherUI')
MonkeyRunner.sleep(3)
device.startActivity(component='com.tencent.mm/com.tencent.mm.ui.LauncherUI')
device.drag((288,204),(288,1024),3,1)
MonkeyRunner.sleep(3)
result = device.takeSnapshot()
result.writeToFile('d:\\simp.png','png') 

(3)运行

精通移动App测试实战:技术、工具和案例_第19张图片

精通移动App测试实战:技术、工具和案例_第20张图片

 

5.5MonkeyRunner样例脚本

1、按Home键

From com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection()

device.press(‘KEYCODE_HOME’,MonkeyDevice.DOWN_AND_UP)

2、设备重启

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection()

device.reboot()

3、设备唤醒

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection()

device.wake()

4、按菜单键

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection()

device.press()

5、输入内容

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection()

device.type(‘monkeyrunner’)

6、控制多个设备

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device1 = MonkeyRunner.waitForConnection(5,’连接设备序列号1’)

device2 = MonkeyRunner.waitForConnection(5,’连接设备序列号2’)

device1.press(‘KEYCODE_HOME’,MonkeyDevice.DOWN_AND_UP)

.......

device1.type(‘monkeyrunner’)

device2.press(‘KEYCODE_HOME’,MonkeyDevice.DOWN_AND_UP)

........

device2.type(‘testing’)

7、对比截屏和已存在图片

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection(5,’b88886a88d’)

result = device.takeSnapshot()

result.writeToFile(‘D:\\result.png’,’png’)

Pic2 = MonkeyRunner.loadImageFromFile(‘D:\\picture2.png’)

If(result.sameAs(Pic2,0.9)):

print(“Success”)

else:

print(“Failure”)

 

8、单击操作

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection(5,’b88886a88d’)

device.touch(200,300,’DOWN_AND_UP’)

 

9、安装APK包

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection(5,’b88886a88d’)

device.installPackage(“f:\\SimpleApp.apk”)

 

10、卸载APK包

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection(5,’b88886a88d’)

device.removePackage(‘com.android.chrome’)

 

11、启动Activity

from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImage

device = MonkeyRunner.waitForConnection(5,’b88886a88d’)

Device.startActivity(component=’simple.app/simple.app.SimpleAppActivity’)

第6章 Robotium 自动化测试框架

6.1Robotium 自动化测试框架简介

是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,提供模拟各种手势操作、查找和断言机制的API,能够对各种控件进行操作。Robotium结合Android官方提供的测试框架可以对应用程序进行自动化测试。另外Robotium4.0已经支持对Web View的操作。Robotium对Activity,Dialog,Toast,Menu也都是支持的。

6.2Robotium环境搭建

  1. 安装JDK并配置环境变量
  2. 安装Eclipse用于脚本编写
  3. 安装配置Android SDK

6.3第一个Robotium示例(针对记事本应用程序)

  1. 记事本样例下载
  2. 记事本样例导入到Eclipse
  3. 记事本样例项目运行
  4. 记事本样例功能介绍
  5. Robotium测试用例项目目录结构
  6. Robotium测试用例实现代码

 

/*
 * This is an example test project created in Eclipse to test NotePad which is a sample 
 * project located in AndroidSDK/samples/android-11/NotePad
 * 
 * 
 * You can run these test cases either on the emulator or on device. Right click
 * the test project and select Run As --> Run As Android JUnit Test
 * 
 * @author Renas Reda, [email protected]
 * 
 */

 

(1)package com.robotium.test;

import com.robotium.solo.Solo;
import com.example.android.notepad.NotesList;
import android.test.ActivityInstrumentationTestCase2;

上面这段代码引入运行Robotium封装好的“com.robotium.solo.Solo”,被测试的“com.example.android.notepad.NotesList”和“ActivityInstrumentationTestCase2”测试用例

(2)public class NotePadTest extends ActivityInstrumentationTestCase2{

 

         private Solo solo;

上面的代码首先创建了一个“NotePadTest”类,它继承了“ActivityInstrumentationTestCase2”类,ActivityInstrumentationTestCase2泛型类的参数类型是MainActivity,这样大家就需要指定待测试的应用的MainActivity,这里待测试的应用的MainActivity就是NotesList,而且它只由一个构造函数需要指定一个待测试的MainActivity才能创建测试用例;然后定义了一个Robotium Solo类型的变量solo,接下来是NotePadTest构造函数:

 

         public NotePadTest() {

                  super(NotesList.class);

 

         }

构造函数需要指定一个待测试的MainActivity才能创建测试用例

        

@Override
	public void setUp() throws Exception {
		//setUp() is run before a test case is started. 
		//This is where the solo object is created.
		solo = new Solo(getInstrumentation(), getActivity());
	}

	@Override
	public void tearDown() throws Exception {
		//tearDown() is run after a test case has finished. 
		//finishOpenedActivities() will finish all the activities that have been opened during the test execution.
		solo.finishOpenedActivities();
	}

上面的代码,setUp()函数是在运行测试用例之前做一些准备性工作,通常会通过调用getInstrumentation()和getActivity()函数来获取当前测试的仪表盘对象和待测试应用启动的活动对象,并创建Robotium自动化测试机器人solo实例。tearDown()函数是在测试用例运行完之后做的一些收尾性的工作,通过finishOpenedActivities()能够关闭所有在测试用例执行期间打开的Activity。

public void testAddNote() throws Exception {
		//Unlock the lock screen
		solo.unlockScreen();//解锁屏幕,只支持非安全的锁
		solo.clickOnMenuItem("Add note");//单击菜单键按钮并选择“Add note”菜单项
		//Assert that NoteEditor activity is opened
		solo.assertCurrentActivity("Expected NoteEditor activity", "NoteEditor"); //判断单击了“Add note”菜单项以后当前的Activity是否为“NoteEditor”
		//In text field 0, enter Note 1
		solo.enterText(0, "Note 1");

         精通移动App测试实战:技术、工具和案例_第21张图片

                  solo.goBack();

单击返回键,输入的“Note 1”就自动保存并返回到了“Notes” Activity

                 

//Clicks on menu item
solo.clickOnMenuItem("Add note");
//In text field 0, type Note 2
solo.typeText(0, "Note 2");
//Go back to first activity
solo.goBack(); 

上面的代码实现了添加“Note2”便笺并返回到“Notes”Activity的目的

 

//Takes a screenshot and saves it in "/sdcard/Robotium-Screenshots/".
		solo.takeScreenshot();
		boolean notesFound = solo.searchText("Note 1") && solo.searchText("Note 2");
		//Assert that Note 1 & Note 2 are found
		assertTrue("Note 1 and/or Note 2 are not found", notesFound); 
	}

                 上面的代码是截取当前屏幕,截屏后图片保存在“/sdcard/Robotium-Screenshots/”路径下,

         从testAddNote()函数的名字我们可以很清楚的知道,这是测试记事本信息添加的测试用例

public void testEditNote() throws Exception {
		// Click on the second list line
		solo.clickLongInList(2); //单击列表的第二条信息
		solo.clickOnText("Edit title");
		// Change orientation of activity
		solo.setActivityOrientation(Solo.LANDSCAPE);//设置手机屏幕横向显示
		//In first text field (0), add test
		solo.enterText(0, " test");  
		//solo.goBack();
		solo.setActivityOrientation(Solo.PORTRAIT);//设置手机屏幕纵向显示
		// (Regexp) case insensitive
		boolean noteFound = solo.waitForText("(?i).*?note 1 test"); 
		//Assert that Note 1 test is found
		assertTrue("Note 1 test is not found", noteFound); 
	}
	
	public void testRemoveNote() throws Exception {
		//(Regexp) case insensitive/text that contains "test"
		solo.clickOnText("(?i).*?test.*");
		//Delete Note 1 test
		solo.clickOnMenuItem("Delete");//按菜单键并从弹出的菜单中单击“Delete”菜单项

		//Note 1 test should not be found
		boolean noteFound = solo.searchText("Note 1 test");
		//Assert that Note 1 test is not found
		assertFalse("Note 1 Test is found", noteFound);  

		solo.clickLongOnText("Note 2");//当前界面上找到“Note 2”内容
		//Clicks on Delete in the context menu
		solo.clickOnText("Delete");//当前界面上包含“Delete”文本内容的地方执行单击操作  
		//Will wait 100 milliseconds for the text: "Note 2"
		noteFound = solo.waitForText("Note 2", 1, 100);
		//Assert that Note 2 is not found
		assertFalse("Note 2 is found", noteFound);  
	}
}

  7、测试用例设计思路分析

记事本样例测试用例设计很值得学习和借鉴,主要基于以下几点:

  1. 这个基于记事本应用的测试用例设计覆盖了记事本便笺信息添加、记事本便笺信息修改和记事本便笺删除所有主要的功能,我们平时在做功能测试时肯定也需要覆盖这些测试内容,所以这是测试用例设计的一个好的地方;
  2. 这个基于记事本应用的测试用例设计还覆盖到了基于不同用户的操作习惯而产生的基于相同功能不同操作的场景,如删除便笺,我们可以发现其既提供了按菜单键后单击“Delete”菜单项进行删除,又提供了长按要删除的便笺、在弹出的快捷键菜单选择“Delete”菜单项进行删除的方式,这也是该测试用例设计的一个优点;
  3. 这个基于记事本应用的测试用例设计还做到了保持手机的初始环境或者说是原始环境,这对于测试来讲很重要,如果每次操作都产生了一些遗留的测试数据,每次执行的环境都不一样,那么测试结果的准确性无疑会有很大问题。但是,在该测试用例设计中,其操作是按照比便笺添加、便笺编辑和便笺删除这样的操作顺序执行的,我们在执行测试用例故意在该便笺中添加一个“Test”标题的便笺,尽管执行过程中同样涉及到了便笺的添加、修改和删除操作,但是都没有对数据造成任何影响。用例执行完成后,除了“Test”便笺以外,没有产生任何遗留测试数据,这样也就爆出了原始的测试环境,这是一个很好的测试用例设计。
  4. 这个基于记事本应用的测试用例设计的代码注释也做到了很好,对于其他测试人员阅读、理解该测试用例设计是大有裨益的。

 

8、Robotium测试用例执行过程

 

6.4用Robotium实现对APK或有源码的项目实施测试

平时进行移动平台应用的测试过程中,主要涉及到了2类应用:

  1. 一类是基于有源代码进行的项目测试,这一类通常都是本单位研发的一些项目,研发部门对测试人员高度信任,可以提供源代码给测试人员,方便测试开发或者白盒测试人员对项目实施自动化测试
  2. 一类是仅有“APK”安装包,我们没有办法得到被测试移动平台应用的源代码

 

1、基于有源码应用的Robotium自动化测试

2、基于APK包应用的Robotium测试项目

(1)由于安卓系统处于安全性等方面的一些考虑,首先必须保证APK包和Robotium测试项目具有相同的签名,“数字签名”以数字化进行处理

以QQ为例:

精通移动App测试实战:技术、工具和案例_第22张图片

签名成功后:将产生一个以debug keystore为该APK重新签名的安装包文件

注意:模拟器上打开QQ点击登录时出现闪退现象

 

以“今日头条”举例,软件在模拟器上可正常开启

精通移动App测试实战:技术、工具和案例_第23张图片

精通移动App测试实战:技术、工具和案例_第24张图片

6.5用Robotium Recorder录制脚本

是一款商用插件,提供一段时间的免费试用

  1. Robotium Recorder插件的安装
  2. 应用Robotium Recorder录制有源代码项目
  3. 应用Robotium Recorder录制APK包应用

精通移动App测试实战:技术、工具和案例_第25张图片

  1. Use sleeps:如果想要测试用例在回放时也同样使用录制时的相同的速度,请选择该方式,此种方式对于较慢的应用程序(带宽密集型或混合应用程序)是一个比较好的选择。
  2. Keep app data:如果选择这种方式时,可选择是否要保留应用程序的数据相关信息。
  3. Identify class over string:默认的视图标识通常就是资源ID。如果资源丢失,可选择一个视图类标识符来代替字符串标识符(即视图中显示的文字)。
  4. Click and drag coordinates:此种方式将记录用户在手机屏幕上点击和拖动坐标过程操作。

 

6.6Robotium获取控件的方法

1、根据控件的ID获取控件

R.java文件中

精通移动App测试实战:技术、工具和案例_第26张图片

注:运行NotePadTest项目时,提示运行需要API-23,用API-23创建的Phone_23模拟器启动速度很慢,一直处于黑屏启动状态

 

2、根据光标位置获取控件

Robotium测试框架提供了非常丰富的接口方法来对Activity上面的控件进行操作。在使用Robotium自动化测试框架进行脚本开发的过程中,会经常使用框架提供的一些类的属性和方法,可通过访问http://robotium.googlecode.com/svn/doc/index.html

 

6.7测试用例脚本的批量运行

因产品部分上线和添加新功能等,在有限时间不能进行系统测试时,就需要选择性的进行一次冒烟测试或者进行一次CheckList测试。需要根据不同测试情况选择不同的测试策略,选择不同优先级的测试用例来执行,就涉及到如何让测试用例脚本批量运行的问题。

1、测试用例管理

JUnit框架的TestSuite可以用来集中放置测试类,这里说的测试类即单元测试用例

以NotePadTest测试项目为例,将增、改、删的测试用例分别放到不同的Java文件中,保持用例设计的“原子性”,方便日后我们调用。

精通移动App测试实战:技术、工具和案例_第27张图片

MyTestSuite.java文件内容

package com.robotium.test.testsuite;
/*引入要执行的测试类和Junit框架的TestSuite*/
import com.robotium.test.NotePadAddTest;
import com.robotium.test.NotePadDeleteTest;
import com.robotium.test.NotePadEditTest;
import junit.framework.TestSuite;
/*新建一个TestSuite,并将相应的测试类添加到该TestSuite,然后返回该TestSuite*/
public class MyTestSuite {
	public static TestSuite getTestSuite() {
		TestSuite suite = new TestSuite();
		suite.addTestSuite(NotePadAddTest.class);
		suite.addTestSuite(NotePadEditTest.class);
		suite.addTestSuite(NotePadDeleteTest.class);
		return suite;
	}
}

2、测试用例执行

3、生成测试报告

(1)0需要向项目中添加android-junit-report-1.5.8.jar包

(2)在AndroidManifest.xml文件中添加“WRITE_EXTERNAL_STORAGE”权限

(3)修改AndroidManifest.xml文件

6.8持续集成

1、什么叫持续集成

大师Martin Fowler对持续集成的定义:是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化构建(包括版本编译,发布,自动化测试)来验证,从而尽快地发现集成错误。许多团队发现这个过程可以大大减少集成的问题,建立开发团队对产品的信心,因为他们可以清楚的知道每一次构建的结果。

2、持续集成环境部署

挑选Jenkins、Tomcat、Ant和Robotium来实现被测试项目的持续集成

3、创建Jenkins job

SVNSpot项目相关详细信息

精通移动App测试实战:技术、工具和案例_第28张图片

精通移动App测试实战:技术、工具和案例_第29张图片

4、生成build.xml文件

(1)切换到我的项目的工作目录D:\eclipse-workspace

运行 android update project -p NotePad 命令 则在NotePad项目下产生了build.xml文件

(2)运行android update test-project -m ../NotePad -p NotePadTest命令在测试项目下产生build.xml文件

  1. 切换到测试项目目录下 运行ant debug

注:只有测试工程的keystore和被测试项目的keystore一致才可以应用Robotium进行相关的用例设计、执行等工作,所以就需要对签名完的APK进行重签名

 

5、安装测试包和被测试包

cd ./NotePadTest
ant clean debug

adb install ./NotePad/bin/NotesList-debug.apk
adb install ./NotePadTest/bin/NoteListTest-debug.apk
adb shell am instrument -w
com.jayway.test/com.zutubi.android.junitreport.JUnitReportTestRunner

6、Jenkins配置测试报告

set ReportPath = /data/data/com.example.android.notepad/files/
set LocalPath = D:/eclipse-workspace
adb pull %ReportPath%junit-report.xml %LocalPath%junit-report.xml

7、验证持续集成成果

8、关于集成思路拓展

第7章 自动化测试工具-UI Automator

7.1为什么选择UI Automator

1、Robotium优点和缺点

  1. 优点:目前国内外用的比较多,书籍和资料相对也较多,社区也比较活跃
  2. 缺点:不能做任何跨进程的操作,不足的原因是该框架本身基于instrumentation测试框架

好的地方是通过instrumentation注入到被测进程,从而与被测进程运行在同一进程空间,使它能非常方便的识别被测应用中的被测对象,并对这些对象进行操作。不好的地方是既然Robotium已经跟被测应用放到了同一进程空间,那么根据Android的进程隔离机制,它自然也被系统隔离在其他进程之外,无法跨进程操作任何对象。

2、UI Automator准确的说是一个测试的Java库,包含了创建UI(用户界面)测试的各种API和执行自动化测试的引擎,其接口丰富、易用,可以支持所有Android事件操作,我们可以通过断言和截图验证正确性,非常适合做UI测试

 

7.2UI Automator演示示例

UI Automator Viewer是用来解析手机界面上的UI控件元素,UI Automator是一个Java库,它包含了UI功能测试的API,且支持自动化脚本的管理和执行

 

1、UI Automator Viewer工具使用介绍

精通移动App测试实战:技术、工具和案例_第30张图片

应用程序主要分为4部分:即手机界面展示区域、工具条区域、结构树区域和节点属性区域

  1. 工具条区域:共有4个按钮。从左至右分别用于:打开已保存的布局,获取详细布局,获取简洁布局,保存布局。点击保存,将存储两个文件,一个是图片文件,一个是.uix文件(XML布局结构) 

2、应用UI Automator等完成单元测试用例设计基本步骤

  1. 启动要测试的APP应用
  2. 连接测试设备至电脑
  3. 运行uiautomatorviewer.bat,并截取手机屏幕
  4. 找到对应元素的属性信息,即找出按键1、2、+、= 的相关信息
  5. 应用Eclipse、UI Automator、Ant等工具来设计单元测试用例,编译项目
  6. 将形成的Jar包分发到手机设备上,运行测试用例并分析测试结果

精通移动App测试实战:技术、工具和案例_第31张图片

3、理解UI Automator Viewer工具捕获的元素属性信息

UI Automator就是通过应用界面上与相应的的组件元素对应的类似的这些属性来定位的

 

按键“1”对应属性信息                                                             按键“2”对应的属性信息

精通移动App测试实战:技术、工具和案例_第32张图片        精通移动App测试实战:技术、工具和案例_第33张图片

 

 

4、UI Automator运行环境搭建过程

  1. JDK
  2. SDK(API高于16)
  3. Eclipse(安装ADT插件)
  4. ANT(用于编译生成的jar)

5、编写第一个UI Automator测试用例

TestCase1.java文件

package yuy.test.lessons;

import com.android.uiautomator.core.UiDevice;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
import android.os.RemoteException;


public class TestCase1 extends UiAutomatorTestCase {
	public void testCalc() throws UiObjectNotFoundException,RemoteException{
		/*用于唤醒手机*/
		UiDevice device = getUiDevice();
		device.pressHome();
		device.wakeUp();
		device.swipe(100, 100, 100, 500, 5);
		
		UiObject tv = new UiObject(new UiSelector().className("android.view.View").instance(2));//获得view对象
		assertTrue("The view dose not that contains the calculator application icon.",tv.exists());//加入断言语句确认是否成功获得了这个对象
		System.out.println("The view has been found.");
				
		UiObject calcico =tv.getChild(new UiSelector().className("android.widget.TextView").instance(3));//获得“计算器”应用图标对象
		assertTrue("The icon dose not exist.",calcico.exists());//判断“计算器”应用图标对象是否存在
		System.out.println("The icon has been found.");
		calcico.click();
		
		sleep(1000);
		
		UiObject btn1 = new UiObject(new UiSelector().index(0));
		assertTrue("The '1' button is not found.",btn1.exists());
		btn1.click();
		
		UiObject btnplus = new UiObject(new UiSelector().index(3));
		assertTrue("The '+' button is not found.",btnplus.exists());
		btnplus.click();
		
		UiObject btn2 = new UiObject(new UiSelector().index(1));
		assertTrue("The '2' button is not found.",btn2.exists());
		btn2.click();
		
		UiObject btnequal = new UiObject(new UiSelector().index(2));
		assertTrue("The '=' button is not found.",btnequal.exists());
		btnequal.click();
		
		UiObject edtresult = new UiObject(new UiSelector().className("android.widget.EditText"));
		System.out.println("Output Result:\r\n"+edtresult.getText());
		assertTrue("The results should be 3 !",edtresult.getText().contains("3"));
		
	}

}

6、查看已安装的SDK版本

7、创建build.xml等相关文件

精通移动App测试实战:技术、工具和案例_第34张图片

创建一个UI测试项目

android create uitest-project -n FirstPrj -t 2 -p D:\eclipse-workspace\FirstPrj

精通移动App测试实战:技术、工具和案例_第35张图片

将default=help 修改成 default=build

右键build.xml -debug as-Ant Build

精通移动App测试实战:技术、工具和案例_第36张图片

 

8、上传生成JAR文件到手机

adb push D:\eclipse-workspace\FirstPrj\bin\FirstPrj.jar data/local/tmp

9、运行测试用例并分析测试结果

adb shell uiautomator runtest FirstPrj.jar -c yuy.test.lessons.TestCase1

 

7.3 UI Automator 

uiautomator API包含关键类,可以用来捕获和操控待测试安卓应用的UI组件元素

1、UiDecice类及其接口调用实例

UiDecice代表设备状态,在测试时可以调用UiDevice类实例的方法来检查不同属性的状态

例子1:

UiDevice.getInstance().pressHome();或getUiDevice().pressHome();

解释:实现按Home键操作

精通移动App测试实战:技术、工具和案例_第37张图片

精通移动App测试实战:技术、工具和案例_第38张图片

2、UiSelector类及其接口调用实例

 

UiSelector代表一个搜索UI控件的条件,可以在当前的界面上查询和获取特定元素的句柄

例子1:

UiSelector wx=new UiSelector().textStarsWith(“微”);//用于构建一个以“微”开头的UiSelector对象“wx”

UiObject obj=new UiObject(wx);//以设定条件创建一个对象实例,并将其赋给“obj”对象

obj.click();//调用“obj”对象的单击事件,实现打开“微信”应用的目的

 

3、UiObject类及其接口调用实例

UiObject代表一个UI元素对象。为创建一个UiObject实例,可以通过UiSelector来查找UiObject,待找到实例后,就可以通过实例的方法来进行一些操作,例如单击、拖动、文本输入

例子1:

UiSelector qq=new UiSelector().text(“QQ”);

UiObject obj=new UiObject(qq);

Obj.click();

解释:实现了单击“QQ”应用图标的操作

 

4、UiCollection 类及其接口调用实例

UiCollection继承了UiObjection类,它用于枚举一个容器用户界面元素的目的,可以通过使用其提供的一些方法获取容器内的子元素对象。UiCollection类主要通过、getChildByDescription()、getChildByInstance()和getChildByText()3个方法来获得要查找的对象。

UiCollection对象+“.”+getChildByDescription(childPattern,text);

UiCollection对象+“.”+getChildByInstance(childPattern,instance);

UiCollection对象+“.”+getChildByText(childPattern,text);

第一个参数是UiSelector类型参数,用于查找出所有符合条件的子元素,第二个参数可以指定描述、文本或实例条件,从返回的子元素集中再次进行搜索,这些方法的返回值为UiObject类型

 

5、UiWatcher类及其接口调用实例

UiWatcher类用于处理脚本执行过程中遇到的一些异常情况,用于监听处理这些情况

 

6、UiScrollable类及其接口调用实例

UiScrollable类是UiCollection的子类,是用来专门处理滚动事件的对象,其提供了丰富多样的滚动处理方法

 

7、Configurator类及其接口调用实例

在运行UI Automator时,通过Configurator类来设置或取得UI Automator的主要参数

 

7.4 UI Automator常见问题解答

1、UI Automator对中文支持问题

在Eclipse中或其他IDE中设置合适的字符集

2、UI Automator如何执行单个类里的单个测试用例

adb shell uiautomator runtest  + “已经上传到手机的jar包文件名”+“-c”+“包.类名”+“#”+子用例名称,来调试用例里的某一个子用例

3、UI Automator如何执行单个类里的多个测试用例

(1)adb shell uiautomator runtest  + “已经上传到手机的jar包文件名”+一个或多个“-c 包路径.类名称#子用例”+“#”+子用例名,当有多个执行序列的子用例时之间应用空格分开

(2) adb shell uiautomator runtest FirstPrj.jar -c yuy.test.lessons.TestCase1#test1

adb shell uiautomator runtest FirstPrj.jar -c yuy.test.lessons.TestCase2#test2

adb shell uiautomator runtest FirstPrj.jar -c yuy.test.lessons.TestCase3#test3

adb shell uiautomator runtest FirstPrj.jar -c yuy.test.lessons.TestCase4#test4

 

第8章 自动化测试工具—Appium实战

8.1为什么选择Appium

Appium是一个自动化测试开源工具,支持IOS和Android平台上的移动原生应用、移动web应用和混合应用。

  1. 移动原生应用:是指用IOS或者Android SDK写的应用
  2. 移动web应用:是指使用移动浏览器访问的应用(Appium支持IOS上的Safari和Android上的Chrome)
  3. 混合应用:是指原生代码封装网页视图(原生代码和web内容交互)。例如Phonegap可以帮助开发者使用网页技术写应用,然后用原生代码封装,这些就是混合应用

Appium是一个跨平台工具,允许测试人员使用同样的接口、基于不同的平台(IOS,Android)写自动化测试脚本,大大增加了IOS和Android测试套件间代码的复用性

 

1、Appium的理念

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

 

2、Appium的设计

(1)Appium真正的工作引擎其实是第三方自动化框架,这样我们不需要在本身的应用里植入Appium特定或者第三方代码。即意味着你在测试将发布的应用时会使用以下的第三方框架。

IOS:苹果的UI Automation框架。

Android 4.2+:Google的UI Automator框架

Android 2.3+:Google的Instrumentation框架

(2)Appium把这些第三方框架封装成一套API,即WebDriver API, WebDriver(即 Selenium WebDriver)指定了客户端到服务端的协议

(3)Appium扩充了WebDriver协议,在原有的基础上添加移动自动化相关的API方法

 

3、Appium的相关概念

  1. C/S架构:即客户端/服务器架构。Appium的核心是一个web服务器,提供了一套REST的接口
  2. Session:自动化总是在一个Session的上下文中运行,客户端初始化一个和服务端交互的Session
  3. Desired Capabilities:是一些键值对的集合(如一个map或者hash),客户端将这些键值对发送给服务端,告诉服务端我们想要启动怎样的自动化Session
  4. Appium Server:是用nodejs写的,可以用源码编译或者从NPM直接安装
  5. Appium服务端
  6. Appium.app,Appium.exe:Appium提供了GUI封装的Appium Server下载,它封装了Appium Server的所有依赖元素

 

8.2 Appium环境部署

1、Windows环境部署

以64位Windows 7操作系统为例

  1. 安装Nodejs
  2. JDK的安装配置
  3. Android SDK的安装
  4. Eclipse的安装
  5. ADT的安装配置
  6. ANT的安装和配置过程
  7. Maven的安装和配置过程
  8. Appium的安装和配置过程

2、Appium样例程序下载

3、Selenium类库的下载

4、建立测试工程

 

AndroidContactsTest.java文件源码
package com.saucelabs.appium;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;

import java.io.File;  
import java.net.URL;  
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

public class AndroidContactsTest {
	
	private AppiumDriver driver; 
	    @Before
	    public void setUp() throws Exception{
	    //设置apk的路径,获得程序当前路径System.getProperty("user.dir")
	    File classpathRoot = new File(System.getProperty("user.dir"));
	    File appDir = new File(classpathRoot, "/apps");
	    File app = new File(appDir, "ContactManager.apk");
	    //设置自动化相关参数,运行平台为Android(或ios),与browser_name相矛盾,不能共存,
        //运行的设备为模拟器  Android Emulator
	    
	    DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability("deviceName","Android Emulator");
        capabilities.setCapability("platformVersion","4.4");
        capabilities.setCapability("avd","Phone_19");
        //设置安卓系统版本,要和启动的模拟器平台保持一致
        capabilities.setCapability("app", app.getAbsolutePath()); 
        
        //设置app的主包名和主类名,包名和类名稍后介绍如何获取
        capabilities.setCapability("appPackage", "com.example.android.contactmanager");
        capabilities.setCapability("appActivity", ".ContactManager");
        
        //初始化,在模拟器上启动安装apk
        driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);       
}
@Test
public void addContact(){
   //添加一个联系人到app中
    WebElement el = driver.findElement(By.name("Add Contact"));
    el.click();
    List textFieldsList = driver.findElementsByClassName("android.widget.EditText");
    textFieldsList.get(0).sendKeys("Some Name");
    textFieldsList.get(2).sendKeys("[email protected]");
    driver.swipe(100, 500, 100, 100, 2);
    driver.findElementByName("Save").click();
}    

@After
public void tearDown() throws Exception {
    driver.quit();
}
}

运行结果:

   精通移动App测试实战:技术、工具和案例_第39张图片   精通移动App测试实战:技术、工具和案例_第40张图片

 

Inspector定位应用活动的界面元素:

精通移动App测试实战:技术、工具和案例_第41张图片

8.3 Appium元素定位的3个利器

1、应用UIAutomator Viewer获得元素信息的实例

2、应用Inspector获得元素信息的实例

注意:Windows系统的Appium的Inspector不稳定,建议Windows系统捕获手机应用活动界面相关元素时选择UI Automator Viewer ,苹果系统的Inspector表现却很稳定

3、应用Chrome浏览器ADB插件获得元素信息实例

8.4多种界面控件的定位方法介绍

1、根据ID定位元素

WebElement num_2=driver.findElement(By.id(“com.android.calculator2:id/digit2”));

根据计算器的数字“2”键的ID,捕获到该键(即按钮控件)

 

2、根据Name定位元素

WebElementPlus = driver.findElement(By.name(“+”));

根据计算器“+”键的Name属性,捕获到该键(即按钮控件)

 

3、根据ClassName定位元素

WebElementPlus=driver.findElement(By.className(“android.widget.EditText”));

查找、定位浏览器URL地址文本框,该组件的class为“android.widget.EditText”

 

4、根据Content-desc定位元素

WebElement equal =driver.findElementByAccessibilityId(“equals”);

查找、定位“content-desc”为“equals”,也就是说“内容描述”信息为“equals”控件

 

5、根据Xpath定位元素

WebElement
num_8=driver.findElement(By.xpath(“//android.widget.FrameLayout[0]/
android.widget.LinearLayout[0]/
Android.widget.FrameLayout[0]/ android.widget.LinearLayout[0]/
android.widget.LinearLayout[2]/ android.widget.LinearLayout[0]/
Android.widget.Button[1]”));

XPath相对于ID和名称的方法效率有点慢,布局后面中括号的数字代表索引号(index)

 

8.5 多种界面控件的操作方法介绍

1、长按操作

2、拖曳操作

3、滑动操作

4、多点操作

8.6捕获异常、创建快照

  1. 安装TestNG插件
  2. 创建测试项目
  3. 创建异常监听类
  4. 创建项目测试类
  5. 测试项目运行结果

第9章 移动平台性能测试

9.1 移动平台性能测试简介

1、性能测试的8大分类

(1)性能测试

软件系统的性能包括执行效率、资源占用、系统稳定性、完全性、兼容性、可靠性、可扩展性等。性能测试是为描述测试对象与性能性能相关的特征并对其进行评价而实施和执行的一类测试。主要通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试,通常把性能测试、负载测试、压力测试等统称为性能测试

(2)负载测试

通过逐步增加系统负载,测试系统性能的变化,并最终确定在满足系统性能指标的前提下,系统所能承受的最大负载量的测试

(3)压力测试

压力测试是通过逐步增加系统负载,测试系统性能变化,并最终确定在什么负载条件下系统性能处于失效状态来获得系统能提供的最大服务级别的测试,逐步增加负载使系统某些资源达到饱和甚至失效

(4)配置测试

配置测试主要是通过对被测试软件的软硬件配置的测试,找到系统各项资源的最优分配原则。配置测试能充分利用有限的软硬件资源,发挥系统的最佳处理能力,同时可以将其与其他性能测试类型联合应用,微系统调优提供重要依据

(5)并发测试

并发测试是测试多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或者其他性能问题,所以几乎所有的性能测试都会涉及一些并发测试。

(6)容量测试

容量测试是在一定的软、硬件条件下,在数据库中构造不同数量级的记录数量,通过运行一种或多种业务场景,在一定虚拟用户数量的情况下,获取不同数量级别的性能指标,从而得到数据库能处理的最大会话能力、最大容量等。系统可处理同时在线的最大用户数通常和数据库有关

(7)可靠性测试

可靠性测试是通过给系统加载一定的业务压力(如CPU资源在70%-90%的使用率)的情况下,运行一段时间,检查系统是否稳定。因为运行时间较长,所以通常可以测试出系统是否有内存泄露等问题

(8)失败测试

对于有冗余备份和负载均衡的系统,通过失败测试来检验如果系统局部发生故障,用户能否继续使用系统,用户受多大的影响,如几台机器做均衡负载,一台或几台机器垮掉后系统能够承受的压力。

 

2、移动端的性能指标

移动平台的性能测试除了需要考虑前面提到的性能指标外,还需要考察移动端以下方面的一些性能指标

  • 单位时间耗电量
  • 单位时间网络流量消耗
  • 移动终端相关资源的利用率
  • 业务响应时间

“2-5-8”或者“3-5-10”原则,如果一个系统,当用户发出请求后,系统能在2秒或3秒给予其返回响应数据,用户会觉得系统还不错;如果响应时间为5秒就会觉得还凑合;而一旦响应时间为8秒到10秒甚至响应时间更长给用户的感受就不好了

  • 帧率

每秒的帧数(fps)或者说帧率表示图形处理器处理场面时每秒能够更新的次数

9.2移动端性能测试工具

1、TraceView工具使用介绍

应用程序代码分析工具

精通移动App测试实战:技术、工具和案例_第42张图片

2、SysTrace工具使用介绍

性能分析工具

在Android平台中它主要由3部分组成:

  1. 内核部分:Systrace利用了Linux Kernel中的ftrace功能。若要使用Systrace的话,必须开启kernel中和ftrace相关的模块
  2. 数据采集部分:Android定义了一个Trace类。应用程序可利用该类把统计信息输出给ftrace。同时,Android还有一个atrace程序,可以从ftrace中读取统计信息然后交给数据分析工具处理。
  3. 数据分析工具:Android提供了一个systrace.py(Python脚本文件,位于Android SDK目录/tools/systrace中,其内部将调用atrace程序)用来配置数据采集的方式(如采集数据的标记、输出文件名等)和收集ftrace统计数据生成一个结果网页文件供用户查看。

3、Emmagee工具使用介绍

是网易杭州研究院QA团队开发的一个Android性能监测小工具,主要用于监控单个手机应用的CPU、内存、流量、启动耗时、电量、电流等性能状态的变化,且用户可以自定义配置监控的采样频率以及性能的实时显示、并最终生成一份性能统计文件,发送邮件等

4、查看应用启动耗时

启动耗时分为两类内容:一是应用安装完成后首次启动耗时;另一类是应用已经运行过、有一定数据量的情况下,如果相关的需求可能在不同数量级的多种情况下可以尝试多次启动应用,这对于有些应用启动时动态加载数据是会有很大的差异的

5、获得电池电量和电池温度

6、获得最耗资源的应用

7、获得手机设备电池电量信息

8、获得手机应用帧率信息

 

9.3 LoadRunner

LoadRunner提供了一些基于移动平台的协议和相应的工具

注意:使用adb install命令安装应用时,应用名称中包含空格时安装失败

1、安装HP LoadRunner Mobile Recorder 1.1.0.apk到安卓虚拟机

 

精通移动App测试实战:技术、工具和案例_第43张图片

2、advanced settings 中设置录制脚本的保存路径

3、单击Start Recording开始脚本录制

精通移动App测试实战:技术、工具和案例_第44张图片

 

4、对虚拟机进行一些操作活动

5、单击Stop Recording按钮停止脚本录制

精通移动App测试实战:技术、工具和案例_第45张图片

6、打开录制的脚本文件

你可能感兴趣的:(移动APP测试)