资源描述
Android工程的Robotium自动化测试介绍
一. Android自动化测试手段有哪些?
测试手段1:Monkey
1) 应用程序的开发者可以测试自己应用的鲁棒性。
[鲁棒是Robust的音译,也就是健壮和强壮的意思。
鲁棒性(robustness)就是系统的健壮性。它是在异常和危险情况下系统生存的关键。比如说,计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下,能否不死机、不崩溃,就是该软件的鲁棒性。所谓“鲁棒性”,是指控制系统在一定(结构,大小)的参数摄动下,维持某些性能的特性。根据对性能的不同定义,可分为稳定鲁棒性和性能鲁棒性。以闭环系统的鲁棒性作为目标设计得到的固定控制器称为鲁棒控制器。 ]
2) 设备制造商可以使用Monkey对自己的设配施行压力测试。看设备能坚持多久。
Monkey测试即可以针对全局,也可以正对某个局部(某个 Category, package等等)。 执行简单,效果明显。
测试手段2:Monkeyrunner
Monkeyrunner工具提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器。通过Monkeyrunner,您可以写出一个Python程序去安装一个Android应用程序或测试包,运行它,向它发送模拟击键,截取它的用户界面图片,并将截图存储于工作站上。Monkeyrunner工具的主要设计目的是用于测试功能/框架水平上的应用程序和设备,或用于运行单元测试套件。
Monkeyrunner工具与monkey并无关联。monkey工具直接运行在设备或模拟器的adbshell中,生成用户或系统的伪随机事件流。而Monkeyrunner工具则是在工作站上通过API定义的特定命令和事件控制设备或模拟器。
测试手段3: ASE
ASE 意思为 Android 脚本环境, 即我们可以通过脚本(比如 Python)调用 Android 的功能,从而定制一些测试。比如打电话,发短信,浏览网页,等。
我们可以扩充它的API(Java 部分), 并用python 脚本调用这些 API, 从而实现丰富的测试功能。
用于API 部分可以访问到Android全部API, python又能灵活部署测试,所以 ASE 的扩展性非常好。
测试手段4: Robotium
该工具用于黑盒的自动化测试。可以在有源码或者只有APK的情况下对目标应用进行测试。
Robotimu 提供了模仿用户操作行为的API,比如在某个控件上点击,输入 Text 等等。
测试手段5:单元测试
Android 本身带有很多单元测试例子,我们可以按需要模仿它们,针对某个
应用进行单元测试。
注意 Android 的Instrument机制功能非常强大,可以测试 UI。
以上各测试方法均有其不同的使用场合及范围,在实际测试过程中我们应该根据测试重点不同而选择不同的测试方法。本文将着重介绍Robotium自动化测试方法。
二. Robotium简介
Robotium是一个测试框架,能够方便你为Android应用程序编写强大、健壮的自动化黑盒测试用例。利用Robotium的支持,用例开发人员能够编写功能、系统和验收测试方案,跨越多个 Android activities。Robotium支持Activities、Dialogs、Toasts、Menus和Context Menus。
Robotium自动化测试方法能够模仿普通用户行为,可以试着把一些原来由测试工程师做的测试变成Robotium自动化实现。
Robotium 提供下列好处
1.以最小的应用程序知识,开发功能强大的测试案例。
2.框架支持多个activities 自动活动。
3.最短的时间需求写出测试用例。
4.测试案例的可读性比标准的仪器测试大大提高。
5.通过运行时绑定GUI组件使测试用例更强大。
6.执行测试用例速度快。
7.顺利整合了Maven或Ant来运行测试,持续集成的一部分。
三. Robotium测试工程创建
确保环境
1.已经安装eclipse
2.Eclipse已经配置好android相关环境
3.存在已经创建模拟器
4.存在一个编译通过的被测工程
这里以AndroidSDK/samples/android-9/NotePad为例:
在Eclipse中导入该工程 File --> New --> Project --> Android Project --> Create Project from existing source --> NotePad.
步骤
1. 在官方down栏下下载所需要的jar包
地址:
2.创建一个Test Project
1)打开eclipse,选择File -> New -> Project… -> Android -> Android Test Project,点击Next。
2)在Test Project Name中输入测试工程的名称,如:NotePadTest。选择An existing Android Project,点击右边的Browse…按钮。
3)选择被测工程NotesList,点击OK按钮,会自动选择和输入Build Target和Properties,可以按照默认的,不用修改。
4)点击Finish按钮,一个新建的测试工程(NotePadTest)就创建好了。
3.创建一个Test Case
1)在NotePadTest -> src -> com.example.android.notepad.test上,右击选择New -> JUnit Test Case,创建一个Test Case。
2)在Name中输入Test Case的名字NotePadTest。
3)Superclass改为android.test.ActivityInstrumentationTestCase2。
4)选择创建setUp()、tearDown()和constructor后,点击Finish按钮。
4.导入robotium.jar
1)选择测试工程NotePadTest右击,选择Build Path-> Configure Build Path…
2)在打开的Properties for NotePadTest中点击Add External JARs…按钮。
3)导入本机中的robotium-solo-2.2.jar文件,击OK按钮。
5.修改java Compiler
1)选择测试工程NotePadTest右击,选择Properties -> java Compiler -> Enable project specific settings。Compiler complicance level选择1.6,点击OK按钮。
6.编写Robotium测试程序
1)导包
//导入需要测试的工程
import com.example.android.notepad.NotesList;
//robotium提供的测试用类
import com.jayway.android.robotium.solo.Solo;
//测试工程要继承用来测试activity的父类
import android.test.ActivityInstrumentationTestCase2;
2)泛型写需要测试的工程的入口activity名NotesList。
public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList>{
…
}
3)修改构造方法
public NotePadTest(String name) {
super("com.example.android.notepad", NotesList.class);
}
4) 在测试方法前覆写父类的setUp()方法:
该方法用来初始化solo,绑定对应的Activity。
protected void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
5)在测试方法后覆写父类的tearDown()方法:
该方法用来清理资源垃圾,关闭activity。
protected void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
6)Solo类运用
Solo类中提供了自动点击、取得、拖拽、搜索等各种方法。
声明Solo类型的成员变量private Solo solo;
典型方法:
① 点击:
clickOnButton(int)—Clicks on a Button with a given index.
clickOnButton(String)—Clicks on a Button with a given text.
clickOnCheckBox(int)—Clicks on a CheckBox with a given index.
clickOnView(View)—Clicks on a given View.
clickOnText(String)—Clicks on a View displaying a given text.
clickLongOnText(String)—Long clicks on a given View.
clickOnRadioButton(int)—Clicks on a RadioButton with a given index.
clickOnScreen(float, float)—Clicks on a given coordinate on the screen.
② 取得:
getCurrentActivity()—Returns the current Activity.
getText(String)—Returns a TextView which shows a given text.
getView(int)—Returns a View with a given id.
getEditText(String)—Returns an EditText which shows a given text.
getImage(int)—Returns an ImageView with a given index.
③ 拖拽:
drag(float, float, float, float, int)—Simulate touching a given location and dragging it to a new location.
④ 搜索:
searchText(String)—Searches for a text string and returns true if at least one item is found with the expected text.
searchEditText(String)—Searches for a text string in the EditText objects located in the current Activity.
searchButton(String, boolean)—Searches for a Button with the given text string and returns true if at least one Button is found.
更多方法请参见Solo的API文档:
7)创建需要的测试方法
可以根据不同目的编写多个测试方法。注意方法名称必须以test开头,程序运行会自动调用以test开头的方法。每次调用测试方法都会运行一次测试工程。下面是测试程序完整代码:
package com.example.android.notepad.test;
import android.test.ActivityInstrumentationTestCase2;
import com.jayway.android.robotium.solo.Solo;
import com.example.android.notepad.NotesList;
public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList>{
private Solo solo;
public NotePadTest() {
super("com.example.android.notepad", NotesList.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
public void testAddNote() throws Exception {
solo.clickOnMenuItem("Add note");
//Assert that NoteEditor activity is opened
solo.assertCurrentActivity("Expected NoteEditor activity", "NoteEditor");
//In text field 0, add Note 1
solo.enterText(0, "Note 1");
solo.goBack(); //Go back
solo.clickOnMenuItem("Add note"); //Clicks on menu item
solo.enterText(0, "Note 2"); //In text field 0, add Note 2
//Go back to first activity named "NotesList"
solo.goBackToActivity("NotesList");
boolean expected = true;
boolean actual = solo.searchText("Note 1") && solo.searchText("Note 2");
//Assert that Note 1 & Note 2 are found
assertEquals("Note 1 and/or Note 2 are not found", expected, actual);
}
public void testEditNote() throws Exception {
solo.clickInList(2); // Clicks on the second list line
// Change orientation of activity
solo.setActivityOrientation(Solo.LANDSCAPE);
solo.clickOnMenuItem("Edit title"); // Change title
solo.enterText(0, " test");//In first text field (0), add test.
solo.goBackToActivity("NotesList");
boolean expected = true;
// (Regexp) case insensitive
boolean actual = solo.searchText("(?i).*?note 1 test");
//Assert that Note 1 test is found
assertEquals("Note 1 test is not found", expected, actual);
}
public void testRemoveNote() throws Exception {
//(Regexp) case insensitive/text that contains "test"
solo.clickOnText("(?i).*?test.*");
solo.clickOnMenuItem("Delete"); //Delete Note 1 test
//Note 1 test & Note 2 should not be found
boolean expected = false;
boolean actual = solo.searchText("Note 1 test");
//Assert that Note 1 test is not found
assertEquals("Note 1 Test is found", expected, actual); solo.clickLongOnText("Note 2");
//Clicks on Delete in the context menu
solo.clickOnText("(?i).*?Delete.*");
actual = solo.searchText("Note 2");
//Assert that Note 2 is not found
assertEquals("Note 2 is found", expected, actual);
}
public void tearDown() throws Exception {
try {
//Robotium will finish all the activities that have been open
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
7.运行测试程序
选择测试工程NotePadTest右击,选择Run As->Android JUnit Test,运行测试程序。测试程序运行log如下:
测试程序运行中的部分截图:
测试成功的情况下,测试结果如下:
测试失败的情况下,测试结果如下:
以上步骤是在eclipse中进行测试的,也可以在模拟器或者手机上测试。如果需要直接在模拟器或者手机上测试,需要将测试包和被测试包改成相同的签名。
展开阅读全文