WeTest简介
说起Android自动化测试,相信很多朋友都接触过或者听说过。 本文首先介绍框架最基本的功能和API的使用,结合简单的项目实践,帮助大家进一步了解和加深对框架的印象。 。 下面我们就来看看标准App自动化测试的四大法宝吧!
法宝一:稳定性测试工具——Monkey
为了发布新版本,必须首先通过稳定性测试。 理想的情况是找一个上幼儿园的弟弟妹妹,打开应用,把手机递给他,让他随机玩,看看你的程序能不能容忍这样的麻烦。 但我们身边不可能都有Shota和Loli,我们也不能保证他们拿到手机的时候不会测试软件的稳健性,而是测试你的手机是否能承受摔落。 这与我们的预期相差甚远……
考虑到我们的需求,Google 开发了 Monkey 工具。 但在很多人的印象中,猴子测试就是让设备随机乱搞,事件随机产生,没有任何人的主观性。 很少有人知道Monkey还可以用来做简单的自动化测试。
Mokey基本功能介绍
首先介绍一下Monkey的基本使用。 如果你想发送 500 个随机事件,只需运行以下命令:
插入手机并运行后,您是否注意到手机开始疯狂运行? 太简单!
感受了悟空的效果后,我发现这个“悟空”太调皮了,根本无法抵挡! 是否有像“curse”这样的约束命令允许这只猴子在某个包或类中运行? 如果你想让Monkey被牢牢限制在某个包内,命令也很简单:
-p 后面是程序的包名称。 如果想限制为多个包,可以在命令行添加多个包:
这样怎么测试源码软件,“悟空”就无法飞出你的五指山了。
Mokey 编写自动化测试脚本
如果你不能控制“悟空”,只是让它随机乱来,猴子就无法取代黑盒测试用例。 我们能不能想办法控制“悟空”,让他做简单的自动化测试呢? 我们来看看如何使用Monkey来编写脚本。
首先,我们简单介绍一下Monkey的API。 如果你想了解更多,可以去百度或者谷歌查看。
(1)轨迹球事件:DispatchTrackball(参数1~参数12)
(2) 输入字符串事件:DispatchString(String text)
(3)点击事件:DispatchPointer(参数1~参数12)
(4) 启动应用程序:LaunchActivity(String pkg_name, String class_name)
(5)等待事件:UserWait(long sleeptime)
(6)按下键值:DispatchPress(int keyCode)
(7) 长按键值:LongPress(int keyCode)
(8)发送键值:DispatchKey(参数1~参数8)
(9) 打开软键盘:DispatchFlip(Boolean KeyboardOpen)
了解完常用的API之后,我们再来看看Monkey脚本的编写规范。 Monkey script是按照一定的语法规则编写的有序的用户事件流,用于Monkey命令工具的脚本中。 Monkey 脚本通常以以下四个语句开头:
我们来看看一个简单应用的实际应用。 效果很简单,随便输入文字,选择选项,然后提交即可。 提交后需要验证提交后的效果。
将上面的代码保存为HelloMonkey文件,然后将脚本推送到手机的SD卡上。
然后运行:
脚本后面的数字1表示脚本运行的次数。 小伙伴们可以安装附件中的Bugben.apk并运行脚本来感受一下!
Monkey工具总结
Monkey可以编写脚本进行简单的自动化测试,但是它有很大的局限性。 比如不能截图,不能简单支持插件的编写,没有好的方法控制事件流程,不支持录制和回放。 在我们的日常使用中,我们更加注重利用好Monkey的优势。 如果不需要源码,可以不编译直接运行。
法宝2:猴之子-MonkeyRunner
虽然Monkey可以实现一些自动化测试任务,但是它也有很多局限性。 例如,它不支持截图、点击事件基于坐标、不支持录制和回放。 在实际应用中,我们尽量利用Monkey测试的优势。 如果您在日常工作中遇到Monkey工具的问题,这里向您推荐另一个工具MonkeyRunner。
我们也简单介绍一下MonkeyRunner的API。 这里我们重点关注可以实现上述Monkey脚本的API。 对其余API感兴趣的朋友可以自行查看。
(1)等待设备连接:waitForConnection()
(2) 安装apk应用程序:installPackage(String path)
(3) 启动应用程序:startActivity(String packageName+activityName)
(4) 点击事件:touch(int xPos, int yPos, 字典类型)
(5) 输入事件:type(String text)
(6)等待:睡眠(int秒)
(7) 截图:takeSnapshot()
(8) 发送键值:press(字符串名称,字典类型)
MokeyRunner编写自动化测试脚本
我们来看看用 MonkeyRunner 实现的自动化脚本。
将脚本保存为HelloMonkeyRunner.py,与Bugben.apk一起复制到Android SDK的tools目录下,并执行monkeyrunner HelloMonkeyRunner.py
执行完成后效果如上,并会在当前目录下生成HelloMonkeyRunner.png的截图。
MokeyRunner的录制和播放
首先是环境配置。 源码“~\sdk\monkeyrunner\scripts”目录下有monkey_recorder.py和monkey_playback.py。 将这两个文件(这两个文件在附件中)复制到SDK的tools目录下。 从以下代码开始:
运行结果如下图所示:
接下来,使用MonkeyRecorder提供的控件来录制脚本。
录制完成后,导出脚本保存为HelloMonkeyRunnerRecorder.mr。 用文本编辑器打开代码如下:
脚本录制完成后,检查播放脚本是否正常。 重放脚本时执行以下命令:
由于脚本中不包含拉取应用程序的代码,因此您需要在运行应用程序之前手动拉取应用程序。
结果效果很好,达到了我们的预期。
MonkeyRunner工具总结
MonkeyRunner拥有许多强大且易于使用的API,并且支持录制、播放和截图操作。 同样,它不需要源代码,无需编译即可直接运行。 不过,MonkeyRunner 与 Monkey 类似,都是基于控件坐标进行定位。 这种定位方式很容易导致播放失败。
法宝三:单元测试框架-Instrumentation
Monkey和他的儿子都可以通过编写相应的脚本而不依赖于源代码来完成部分自动化测试工作。 但它们都是依靠控制坐标来定位的。 在实际项目中,控制坐标往往是最不稳定的,随时可能因为程序员对控制位置的调整而导致脚本运行失败。 如何在不依赖坐标的情况下对应用程序进行自动化测试? 接下来我们就为大家揭晓自动化测试的屠龙宝剑——Instrumentation框架。
Instrumentation框架主要依靠控件的ID来进行定位。 它拥有成熟的用例管理系统,是Android主要的白盒测试框架。 如果想要对项目进行深入、系统的单元测试,基本上离不开Instrumentation这把屠龙剑。
在了解Instrumentation框架之前,我们先解释一下Android组件生命周期对应的回调函数:
从上图可以看出,当Activity处于不同的状态时,会调用不同的回调函数。 然而,Android API并没有提供直接调用这些回调函数的方法。 这可以在 Instrumentation 中完成。 Instrumentation类通过“钩子”控制Android组件的正常生命周期,控制Android系统加载应用程序。 通过Instrumentation类,我们可以在测试代码中调用这些回调函数,就像调试控件一样,一步步进入控件的整个生命周期。
Instrumentation 和 Activity 有点类似,只不过 Activity 需要一个接口,而 Instrumentation 则不然。 我们可以将其理解为一个具有启动能力的设备,没有图形界面,用于监控其他类(用 Target Package 声明)的工具类。
下面通过一个简单的例子来讲解Instrumentation的基本测试方法。
首先创建一个名为HelloBugben的Project,类名为HelloBugbenActivity,代码如下:
这个程序的功能很简单,就是给两个TextView的内容设置不同的文本格式。
2.对于测试工程师来说,HelloBugben是一个已完成的项目。 接下来需要创建一个测试项目,选择“New->Other->Android Test Project”,命名为HelloBugbenTest,选择要测试的目标项目为HelloBugben项目,然后点击Finish完成测试的创建项目。
可以注意到,这个项目的包名中带有测试标签com.example.hellobugben.test,这意味着测试项目是为HelloBugben设置的。
打开 AndroidManifest 以查看标签。 该标签元素用于指定要测试的应用程序。 com.example.hellobugben 自动设置为 targetPackage 对象。 代码清单如下:
标签中android:name声明测试框架,android:targetPackage指定待测试项目的包名。
我们来看看如何使用Instrumentation框架来编写测试程序。 代码如下:
上面的代码中,我们首先引入import android.test.ActivityInstrumentationTestCase2。 其次,让HelloBugbenTestbase继承自ActivityInstrumentationTestCase2类。 然后在setUp()方法中,通过getActivity()方法获取待测试项目的实例,通过textview1和textview2获取两个TextView控件。 最后编写三个测试用例:控制文本设置测试testSetText()、字体粗体属性测试testSetBold、字体大小属性测试testSetSize()。 这里使用的关键方法是 Instrumentation API 中的 getActivity() 方法。 如果不调用该方法,待测试的Activity将不会启动。
眼尖的朋友可能发现了,这里在控制文本设置测试中启用了一个新线程。 这是因为Android中相关的视图和控件不是线程安全的,必须在新的线程中单独处理,否则会报错误信息。
这个错误。 因此需要启动一个新的线程进行处理。 具体步骤如下:
1)在setUp()方法中创建Handler对象,代码如下:
2)创建一个Runnable对象,并在Runnable中设置控制文本。 代码如下:
3)具体测试方法中,通过调用runnable对象来实现文本设置。 代码如下:
让我们运行一下结果。 结果截图如下:
可以看到3个测试用例结果运行正常。
有的朋友可能要问,为什么程序要继承ActivityInstrumentationTestCase2呢? 我们首先看一下ActivityInstrumentationTestCase2的继承结构:
java.lang.Object
junit.framework.Assert
junit.framework.TestCase
android.test.InstrumentationTestCase
android.test.ActivityTestCase
android.test.ActivityInstrumentationTestCase2
ActivityInstrumentationTestCase2 允许 InstrumentationTestCase.launchActivity 启动被测活动。 而且,ActivityInstrumentationTestCase2还支持在新的UI线程中运行测试方法,并且可以将Intent对象注入到被测Activity中。 这样我们就可以直接操作被测Activity了。 正是因为ActivityInstrumentationTestCase2具有如此突出的功能,它成功地取代了它的老大哥:ActivityInstrumentationTestCase,成为Instrumentation测试的基础。
实践中的仪器测试框架
了解了Instrumentation的基本测试方法后,我们来看看如何使用Instrumentation框架来完成Monkey父子完成的自动化测试任务。
首先创建一个名为Bugben的Project,类名为MainActivity,代码如下:
创建了一个名为OtherActivity的类后,点击提交按钮后,就会跳转到这个界面。 代码如下:
3、接下来需要创建一个测试项目,命名为BugbenTestbase,选择需要测试的目标项目为Bugben项目,然后点击Finish完成测试项目的创建。
将 BugbenTestbase 类添加到 com.ringo.bugben.test 包中。 该类的代码如下:
上述代码一共包含了自动化测试所需的5个步骤,如下:
(1)启动应用程序:通过Intent对象setClassName()方法设置包名和类名,通过setFlags()方法设置标志,然后通过getInstrumentation()的startActivitySync(intent)启动应用程序并进入主界面。
(2)编辑控件:Android中相关的视图和控件不是线程安全的,所以必须在新的线程中单独处理。 代码中,我们在runTestonUiThread(new Runnable())中的run()方法中执行。
(3) 提交结果:点击提交按钮,提交结果。 由于点击按钮也是一个界面操作,所以也需要在runTestOnUiThread线程中完成。
(4)界面跳转:这是Instrumentation自动化测试中最需要注意的一点怎么测试源码软件,特别是如何确认界面发生了跳转。 您可以通过在 Instrumentation 中设置 Monitor 来确认这一点。 代码如下所示:
然后通过waitForMonitor方法等待界面跳转。
如果返回结果otherActivity对象不为空,则说明跳转正常。
(5)验证显示:跳转后使用assertEquals()或assertTrue()方法判断显示的正确性。
让我们运行一下结果。 结果截图如下:
仪器仪表工具总结
Instrumentation框架整体运行流程图如下:
Instrumentation基于源码进行脚本开发,测试稳定性好,可移植性高。 由于是基于源码的,脚本开发人员需要非常熟悉Java语言、Android框架运行机制以及Eclipse开发工具。 Instrumentation框架本身不支持多个应用程序的交互。 例如,在测试“通过短信中的号码拨打电话”的用例时,被测应用程序会从短信应用程序界面跳转到拨号应用程序界面,但Instrumentation没有办法控制这两个文本消息和拨号。 这是因为Android系统本身的安全限制禁止多个应用程序进程之间的相互访问。
法宝四:终极自动化测试框架——UIAutomator
鉴于Instrumentation框架需要了解项目源码、脚本开发难度大且不支持多应用交互,Android官网透露了自动化测试的王牌——UIAutomator,并主要宣传这种自动化测试框架。 该框架不需要项目源码,脚本开发效率高,难度低,支持多个应用交互。 当UIAutomator出来后,Instrumentation框架又回到了它原来作为单元测试框架的位置。
让我们看看这个框架是如何工作的。 首先运行Android SDK的tools目录下的uiautomatorviewer.bat,可以看到启动界面。
启动 bugben 应用程序后,单击
该图标用于收集手机的界面信息,如下图:
我们可以看到用uiautomatorviewer捕获的控件非常清晰,定位元素位置非常方便。 在UIAutomator框架中,测试程序和被测程序之间是松耦合的关系,即不需要获取被测程序的控件ID,只需要获取文本(text)、描述(content- desc)以及需要识别的控件的其他信息。 就是这样。
在进行实战之前,我们先看一下UIAutomator的API部分,它由以下架构图组成。
我们来看看如何使用这个框架来创建一个测试项目。
1.创建BugBenTestUIAuto项目,右键单击该项目并选择Properties > Java Build Path
单击“添加库”>“Junit”>“Junit3”以添加 Junit 框架。
单击“添加外部 Jar”,导航到 Android SDK 目录,然后选择platforms目录下的 android.jar 和 UIAutomator.jar 文件。
2、设置完成后,就可以开始编写项目测试的代码了,如下:
上面的代码中,我们首先引入了import com.android.uiautomator.testrunner.UiAutomatorTestCase类,并让BugbenTest继承自UiAutomatorTestCase类。 同样,我们看一下UiAutomator框架下自动化测试的五个步骤,如下:
(1)启动应用程序:与Instrumentation框架不同,UiAutomator通过命令行启动应用程序。
(2)编辑控件:在UiAutomator框架中,编辑控件比较简单。 直接通过UiSelector的text()方法找到对应的控件,然后调用该控件的setText()为其赋值。
(3) 提交结果:点击提交按钮,提交结果。 也可以通过UiSelector的text()方法找到对应的控件,然后调用clickAndWaitForNewWindow()方法等待跳转完成。
(4)获取界面跳转元素:使用uiautomatorviewer捕获跳转后的控件,例如捕获跳转1后的文本:
(5)验证显示:跳转后使用assertEquals()或assertTrue()方法判断显示的正确性。
至此核心代码部分已经编写完毕。 UIAutomator有一个麻烦:它不能直接通过Eclipse编译。 它可以在一系列命令行的帮助下进行编译。 详细步骤如下:
1)通过以下命令创建编译好的build.xml文件
创建完成后,刷新BugBenTestUIAuto项目,得到下图:
打开build.xml,你会看到编译后的项目名为BugBenTestUIAuto。
2)设置SDK路径:
3)进入测试目录并编译:
编译完成后,再次刷新项目,可以看到bin目录下生成了BugBenTestUIAuto.jar包,如图:
4)将生成的jar包推送到手机上
5)在手机上运行自动化脚本,即jar包中的测试用例。 命令行如下:
运行结果如下,返回OK表示运行成功。
6)最后将手机运行后的截图复制到PC上
至此,整个代码已经编译并运行。 如果调试时觉得反复修改编译麻烦,可以将上述脚本写成批处理文件。
UIAutomator工具总结
与Instrumentation工具相比,UIAutomator工具更加灵活。 它不需要项目源代码,具有可视化界面和可视化树级列表,大大降低了自动化测试脚本开发的门槛。 并且UIAutomator支持多个应用程序的交互,弥补了Instrumentation工具的缺点。 然而,UIAutomator 很难捕获控件的颜色、字体粗细、字体大小等信息。 验证此类信息需要通过截图的方式进行半自动验证。 同时,UIAutomator的调试比Instrumentation更加困难。 因此,在平时的测试过程中,建议将两者结合起来,以获得更好的效果!
关于腾讯WeTest(wetest.qq.com)
腾讯WeTest是腾讯游戏官方推出的一站式游戏测试平台。 它利用腾讯十年的游戏测试经验,帮助开发者在游戏开发的整个生命周期中确保质量。 腾讯WeTest提供:适配兼容性测试; 云端真机调试; 安全测试; 功耗测试; 服务器性能测试; 舆情监测等服务。