Robotium是一个测试框架,能够方便你为Android应用程序编写强大、健壮的自动化黑盒测试用例。利用Robotium的支持,用例开发人员能够编写功能、系统和验收测试方案,跨越多个 Android activities。Robotium支持Activities、Dialogs、Toasts、Menus和Context Menus。
Robotium自动化测试方法能够模仿普通用户行为,可以试着把一些原来由测试工程师做的测试变成Robotium自动化实现。
参考文档:http://www.robotium.cn/
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包
地址:http://code.google.com/p/robotium/downloads/list
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。
publicclass NotePadTestextendsActivityInstrumentationTestCase2<NotesList>{ } |
3)修改构造方法
public NotePadTest(String name) { super("com.example.android.notepad", NotesList.class); } |
4) 在测试方法前覆写父类的setUp()方法:
该方法用来初始化solo,绑定对应的Activity。
protectedvoid setUp()throws Exception { solo =new Solo(getInstrumentation(), getActivity()); } |
5)在测试方法后覆写父类的tearDown()方法:
该方法用来清理资源垃圾,关闭activity。
protectedvoid 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文档:
http://www.jarvana.com/jarvana/view/com/jayway/android/robotium/robotium-solo/2.0.1/robotium-solo-2.0.1-javadoc.jar!/index-all.html
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;
publicclass NotePadTestextends ActivityInstrumentationTestCase2<NotesList>{ private Solosolo;
public NotePadTest() { super("com.example.android.notepad", NotesList.class); }
publicvoid setUp()throws Exception { solo =new Solo(getInstrumentation(), getActivity()); }
publicvoid 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); }
publicvoid 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); }
publicvoid 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); }
|
publicvoid 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
以上步骤是在eclipse中进行测试的,也可以在模拟器或者手机上测试。如果需要直接在模拟器或者手机上测试,需要将测试包和被测试包改成相同的签名。