65.9K
CodeProject 正在变化。 阅读更多。
Home

自动 Android* 应用程序测试

2014年7月22日

CPOL

10分钟阅读

viewsIcon

21964

在本文中,我将回顾几种用于自动化功能测试的工具。我只回顾 Android SDK 中包含的或在开源许可证下分发的工具。

引言

测试是应用程序开发过程中的重要组成部分。对于 Android 来说,这一点尤其重要,因为设备在以下方面差异很大:

  • 屏幕尺寸和分辨率
  • Android 版本
  • 外观尺寸
  • 处理器指令集
  • 是否存在前置摄像头、NFC、外接键盘等。

您的 Android 应用程序应在许多设备上进行测试。

应用程序测试过程包括许多类型的测试。让我们来看一下手动功能测试。测试人员需要仔细检查所有功能,并将设备重置到初始状态。测试人员会为每个应用程序和每台设备重复这些步骤。手动执行此过程非常耗时。

自动化功能测试可以定期执行,无需额外成本。例如,每晚在所有设备上测试一个构建版本,早上分析结果,然后修复错误。

在本文中,我将回顾几种用于自动化功能测试的工具。我只回顾 Android SDK 中包含的或在开源许可证下分发的工具。

自动化测试的概念

我们的目标是自动化手动执行的操作,以实现最大的精确性。让我们回顾一下这些操作。我们将使用几个应用程序和几台 Android 设备。

对于每个应用程序和每台设备,我们需要执行以下步骤:

  1. 在设备上安装应用程序
  2. 启动应用程序
  3. 使用选定的方法测试应用程序
  4. 卸载应用程序
  5. 将设备重置到初始状态

在每个步骤中,您都需要收集和分析日志和屏幕截图等数据。下面,我们将讨论自动化这些步骤的工具。

控制 Android 设备

首先,您需要选择将运行自动化测试的计算机,并在其上安装 Android SDK。我将以装有 Linux* 的台式计算机为例。您需要禁用锁屏,并将“休眠前时间”设置为最大值。对于某些测试方法,您需要禁用屏幕方向更改。

Android SDK 中有两个实用程序用于控制 Android 设备:ADB 和 monkeyrunner*。我将详细介绍如何自动化手动测试中使用的操作。

使用 ADB 控制 Android 设备

ADB (Android Debug Bridge) 是一个用于控制 Android 设备的命令行工具。ADB 主页是:https://developer.android.com.cn/tools/help/adb.html

ADB 工具位于目录 <android_sdk>/platform-tools/ 中。您应该将此目录添加到 PATH 环境变量中。

检查 ADB 安装

安装并配置 Android SDK,然后将 Android 设备连接到您的计算机并运行命令

adb devices

此命令将列出所有已插入的 Android 设备。如果设备列表不为空,则表示 ADB 工作正常。

处理多个设备

您应该使用“-s”参数指定 ADB 要使用的设备。

adb -s [serial_number] [command]

例如

adb -s [serial_number] logcat

设备序列号可以从“adb devices”命令的输出中获得。参数 -s 允许您同时处理多个已连接的设备。

基本 ADB 命令

在设备上打开终端

adb shell

在设备上运行命令

adb shell [command]

Android 中包含许多标准的 Linux 实用程序:ls、cat、dmesg 等。

从 apk 文件安装应用程序

adb install example.apk

卸载应用程序

adb uninstall [package]

从 apk 文件获取软件包名称

aapt dump badging example.apk | grep "Package"

将文件从设备下载到计算机

adb pull [path-on-device] [file]

将文件从计算机上传到设备

adb push [file] [path-on-device]

注意
Android 设备上的大多数目录仅允许读取访问。/sdcard(但不能从此目录运行程序)和 /data/local/tmp 允许写入访问。

启动应用程序

adb shell am start -n [package]/[activity]

运行指定的活动。

您可以从 apk 文件中提取活动名称。

aapt dump badging example.apk | grep "launchable-activity"

读取日志

Logcat 是一个从 Android 设备读取日志的命令。

Logcat 主页:https://developer.android.com.cn/tools/help/logcat.html

从设备读取日志(直到按下 Ctrl-C 才会阻塞)

adb logcat

清除设备上的日志缓冲区

adb logcat -c

转储设备上的日志缓冲区(显示当前缓冲区内容,非阻塞)

adb logcat -d

示例

adb logcat -c # clear the buffer log
# Action
adb logcat -d > file.log # save the current contents of the log buffer to file.log

使用 screencap 捕获屏幕截图

screencap 实用程序将屏幕的当前内容保存到图形文件中。

adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png screen.png
adb shell rm /sdcard /screen.png

screencap 实用程序在 Android 4.x 及更高版本的手机上可用。在之前的 Android 版本上,您可以使用 monkeyrunner 捕获屏幕截图。

用于使用 ADB 测试应用程序的 BASH 脚本

脚本:app_test.sh

使用 MonkeyRunner 控制 Android 设备

monkeyrunner 工具提供了用于控制 Android 设备的脚本 API。您可以使用 monkeyrunner 编写 Python* 脚本,该脚本可以安装 Android 应用程序、启动它、模拟用户操作、捕获屏幕截图并将其保存到您的计算机。Monkeyrunner 使用 Jython* 来运行脚本。

monkeyrunner 主页和 API 参考:https://developer.android.com.cn/tools/help/monkeyrunner_concepts.html

使用 monkeyrunner 读取日志

文件 log.py

# coding: utf-8
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

def log(fn, device):
    msg = device.shell('logcat -d')
    f_log = open(fn, 'at')
    if msg is None:
        msg = 'None'
    f_log.write(msg.encode('utf-8'))
    f_log.close()    
    device.shell('logcat -c')

if __name__ == '__main__':
    device = MonkeyRunner.waitForConnection()
    device.shell('logcat -c') # Clear logs buffer
    # ...
    log('example.log', device) # Write logs

开始

monkeyrunner log.py

脚本会将日志写入当前目录下的文件 example.log。

使用 MonkeyRunner 捕获屏幕截图

文件 screen.py

# coding: utf-8
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

if __name__ == '__main__':
    device = MonkeyRunner.waitForConnection()
    image = device.takeSnapshot()
    image.writeToFile('screenshot.png','png')

开始

monkeyrunner screen.py

脚本会捕获屏幕截图并将其保存到当前目录下的文件 screenshot.png。

使用 monkeyrunner 进行设备控制示例

脚本:monkeyrunner_test.py

开始

monkeyrunner monkeyrunner_test.py

自动化测试方法

使用 Monkey* 进行测试

想象一下,您正在测试的设备被交给了非常活跃且富有创意的猴子——Monkey 工具就是为了模拟这种情况而设计的。Monkey 工具是 Android SDK 的一部分,它会发送一系列随机用户事件。命令行参数指定用户操作的数量、每种事件类型的比例以及包的名称(这样 Monkey 就不会超出被测应用程序的范围,也不会开始向通讯录中的所有联系人发送短信)。

Monkey 主页上的示例和参数列表:https://developer.android.com.cn/tools/help/monkey.html

Monkey 工具的主要优点是零维护成本。此外,压力测试可以检测到非显而易见的错误。

使用 Monkey 工具进行测试的缺点

  • Monkey 无法模拟复杂的负载,例如身份验证。在这种情况下,应用程序功能将未得到测试。
  • 具有复杂控制、需要快速反应和复杂手势的游戏会过早结束,或根本无法开始。
  • Monkey 发现的错误很难重现。
  • Monkey 在测试期间不检查应用程序状态。

使用 Monkey 进行自动化测试是任何应用程序的一个良好起点。该方法有可能为特定应用程序显示足够的结果。如果测试质量很低,您应该使用其他测试方法。

使用 MonkeyRunner 进行测试

您不仅可以使用 MonkeyRunner 开发 Android 设备控制脚本,还可以编写脚本来在特定设备上测试应用程序。

优点

  • 灵活。

缺点

  • 编写脚本的复杂性,即使在简单的情况下也是如此。

开发 monkeyrunner 脚本需要花费大量时间,因此这种方法通常不具有成本效益。然而,在特殊情况下,此方法可能有效。

使用 getevent 和 sendevent 进行测试

Getevent 和 sendevent 实用程序允许用户记录事件序列并重放该序列。运行这些工具不需要 root 权限。

优点

  • 在手动测试(如果执行)时,可以在不产生额外成本的情况下记录事件序列。
  • 记录事件序列不需要编程技能。

缺点

  • 序列应为每个应用程序和每台设备单独记录。如果更改应用程序的界面,所有记录的操作都应重做。
  • 此方法在测试期间不检查应用程序状态。如果应用程序响应延迟(例如,网页加载),测试结果将不正确。
  • 快速和复杂的序列将比记录的时间播放更长。因此,它并不总是适用于测试响应时间至关重要的动态游戏。

记录事件序列

# Record event sequence
# Do actions on the device, press Ctrl-C to finish
adb shell getevent -t > events.txt
# Convert event sequence to script
./decode_events.py events.txt > events.sh
# Load the script to the device
adb push events.sh /data/local/tmp/
# Set the permissions
adb shell chmod 755 /data/local/tmp/events.sh
# Run script
adb shell sh /data/local/tmp/events.sh

脚本:decode_events.py

在设备上重放记录的事件序列。

使用 Robotium* 进行测试

Robotium 不是 Android SDK 的一部分,它在开源许可证下分发。Robotium 主页是:http://code.google.com/p/robotium/

Robotium 脚本在应用程序 UI 级别而不是输入设备级别定义操作。

例如,一个脚本需要点击“OK”按钮。monkeyrunner 脚本将实现为“在屏幕点 (x0, y0) 处点击”。Robotium 脚本将实现为“按下文本为“OK”的按钮”。

当操作在界面级别进行描述时,测试脚本可以独立于界面布局、屏幕分辨率和方向。

此外,Robotium 允许您检查应用程序对操作的响应。例如,点击“OK”按钮后,应该出现带有“Item 1”项的列表。您可以使用 Robotium 检查列表项名称。如果在每一步之后都检查应用程序状态,则很容易确定错误发生在哪个步骤。

缺点

  • 您需要为每个应用程序开发一个 Java* 测试脚本。这需要编程技能和时间。
  • 当应用程序界面发生变化时,需要重做事件序列。
  • 编写 Robotium 脚本比使用 getevent / sendevent 记录事件更难。

总的来说,Robotium 允许您以合理的成本开发最高质量的测试用例。

测试方法比较

测试方法 优点 缺点

Monkey - 一系列随机用户操作

无维护成本。
独立于设备。
压力测试可以检测非平凡的错误。

测试质量因应用程序而异。
难以重现错误报告。

Monkey 在测试期间不检查应用程序的状态。

monkeyrunner - 设备控制脚本

灵活性

脚本的复杂性,即使是对于简单的应用程序。

getevent/sendevent - 记录/重放用户操作

记录事件序列不需要编程技能。

记录的动作序列仅适用于具有固定屏幕方向的单个设备。

当应用程序界面发生变化时,需要重做事件序列。

此方法在测试期间不检查应用程序状态。

Robotium - 用于验证状态的测试脚本 API

操作在应用程序 UI 级别进行描述。

脚本可能独立于屏幕分辨率和屏幕方向。

脚本可以在操作后检查应用程序状态。

用 Java 编写脚本的复杂性。

如果更改应用程序界面,则需要修改脚本。

结果分析

现在我们需要分析在自动化测试过程中收集的日志和屏幕截图中的错误。

日志分析

您可以搜索字符串

  • I/DEBUG
  • FATAL EXCEPTION
  • WIN DEATH

此列表可以根据手动测试期间发现的错误消息进行扩展。

屏幕截图分析

您可以准备一系列测试关键时刻的屏幕截图,并将其与自动化测试期间的屏幕内容进行比较。这将确定自动化测试过程是否正常运行。

比较初始屏幕截图与应用程序启动后的屏幕截图很有用。这有助于检测应用程序悄然失败的情况。

Monkeyrunner 允许您以指定的百分比容差比较两个屏幕截图。

image1 = device.takeSnapshot()
# ...
image2 = device.takeSnapshot()
if image2.sameAs(image1, 0.1):
    print 'image1 and image2 are the same (10%)'

不幸的是,没有 MonkeyImage API 可以从文件中加载图像。您可以使用例如 Python* Imaging Library 编写自定义函数来比较图像。

将设备重置到初始状态

测试后应将设备返回到初始状态。这可以通过几种方式实现:

  • 多次按下“返回”按钮。
  • 重启设备。
  • 重启 zygote 进程。

第一种选择通常是最合适的。

多次按下“返回”按钮

使用 monkeyrunner 按下“返回”按钮

for i in xrange(0, 10):
    device.press('KEYCODE_BACK', MonkeyDevice.DOWN_AND_UP)
    time.sleep(0.5)

在实践中,这是一个不错的选择,因为它模拟了真实用户的行为。

结论

在本文中,我们介绍了 Android 应用程序的几种自动化测试方法。我们回顾了自动化测试方法的优缺点。

我们还讨论了 Android SDK 中包含的 Monkey 和 monkeyrunner 工具以及 Robotium 工具。

自动化测试不能替代其他类型的测试。一个结构合理的测试过程,结合包括自动化测试在内的不同测试方法,是高质量应用程序开发过程的重要组成部分。

其他相关文章和资源

© . All rights reserved.