近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料。

Android测试大致分三大块:

  1. 代码层测试
  2. 用户操作模拟,功能测试
  3. 安装部署及稳定性测试

代码层测试

对于一般java代码,采用传统的Junit测试,开发人员通常会编写重要接口和函数的白盒测试代码,不做过多讨论。

但因Android的特殊运行机制(Dalvik虚拟机),其中存在Application、Activity、Service等特殊组件,而这些组件都涉及到生命周期管理的问题。

为了对这些组件进行测试,Google提供了一套针对性的测试框架,AndroidTestFramework

官方教程链接http://developer.android.com/training/testing.html

官方apihttp://developer.android.com/reference/android/test/package-summary.html

其中最为常用的就是针对Activity的测试,即ActivityInstrumentationTestCase2<T>类。

继承该类后可通过getActivity()方法获取Activity的一个mock对象,从而实现各种界面元素的测试。代码如下

复制代码
public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {        LoginActivityTest mActivity;        Button btnLogin;        public LoginActivityTest(){      super(LoginActivity.class);//必须实现super(testclass)        }        @Override    protected void setUp() throws Exception {        super.setUp();        mActivity = getActivity();                btnLogin = mActivity.findViewById(R.id.btnLogin);    }        public void testGetActivity(){           assertNotNull("can't get LoginActivity" , mActivity);           assertNotNull("can't get loginButton" , btnLogin);        }}
复制代码

需要注意的是,测试代码运行的线程并不是UI线程。因此如果需要对UI元素进行setText或是click之类的操作,需要通过getActivity().runOnUiThread(action)方法执行。代码如下

getActivity().runOnUiThread(new Runnable() {            @Override            public void run() {                 btnLogin.click();            }        });

用户操作模拟,功能测试

虽然AndroidTestFramework可以帮助我们完成各种界面的测试。但是,这些代码的编写非常繁琐。而且在大部分情况下,我们需要的是一个连贯性的,在多个Activity之间存在跳转的业务流程测试。这种测试比较接近传统的白盒测试,只针对可见的UI元素进行操作,模拟用户的行为来完成测试。

Google同样为我们提供了一套专门针对UI元素的测试方案,具体可见http://developer.android.com/tools/testing/testing_ui.html

可是Google的这套UI框架仍然不是很友好。为此,我寻找了一些相对成熟的测试框架来帮助我们。经过一系列分析比较和实际代码测试,在这推荐采用Robotium开源框架做为今后一段时间内的主要业务测试框架。

Robotium介绍

Robotium是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手势操作(点击、长按、滑动等)、查找和断言机制的API,能够对各种控件进行操作。Robotium结合Android官方提供的测试框架达到对应用程序进行自动化的测试。另外,Robotium 4.0版本已经支持对WebView的操作。Robotium 对Activity,Dialog,Toast,Menu 都是支持的。

源码及相关资料地址:https://code.google.com/p/robotium/

Robotium具有清晰的调用方法、良好的兼容性、完善的文档和大量的实际应用案例,并且支持截屏。最为符合我们目前的实际需求。经实际测试,无需特殊配置即可兼容Jenkins系统。
下面以一段HSA项目中的实际测试代码举例。该测试用例完成从登陆、菜单选取、一直到功能界面输入验证的一个流程。

复制代码
public class LoginActivityTest extends ActivityInstrumentationTestCase2<LoginActivity> {    Solo solo;    LoginActivity mActivity;        public LoginActivityTest(){        super(LoginActivity.class);    }        @Override    protected void setUp() throws Exception {        super.setUp();        mActivity = getActivity();//初始LoginActivity        solo = new Solo(getInstrumentation(),mActivity);//初始Robotium的主要入口,solo对象    }        public void testLogin(){        //清除用户名EditText内容        solo.clearEditText(0);        //输入"userName" 到用户名EditText        solo.enterText(0, "userName");                //清除密码EditText内容        solo.clearEditText(1);        //输入"userPass" 到密码EditText        solo.enterText(1, "userPass");                //清除站点EditText内容        solo.clearEditText(2);        //输入"siteCode" 到站点EditText        solo.enterText(2, "siteCode");                //点击登陆按钮        solo.clickOnButton("登录");                //检验当前界面为MainListActivity        solo.assertCurrentActivity("Expected MainListActivity activity", "MainListActivity");                //点击动态菜单列表中的第一项,进入下一级子菜单界面        solo.clickInList(0);        //检验当前界面为SubMenuActivity        solo.assertCurrentActivity("Expected SubMenuActivity activity", "SubMenuActivity");                //点击子菜单列表中的第一项,进入功能界面        solo.clickInList(0);        //检验当前界面为ReceiveActivity        solo.assertCurrentActivity("Expected ReceiveActivity activity", "ReceiveActivity");                //点击界面中的"使用当前人员"按钮        solo.clickOnButton("使用当前人员");        //输入重量        solo.enterText(1, "123");                //输入单号        solo.enterText(2, "21123456798");                //模拟软键盘,发送EditText的ACTION_DONE事件        solo.getCurrentActivity().runOnUiThread(new Runnable() {            @Override            public void run() {                solo.getEditText(2).onEditorAction(EditorInfo.IME_ACTION_DONE);            }        });                //寻找是否有内容为"已扫描1件"的textview, 会自动等待10秒        boolean succ = solo.searchText("已扫描1件"))                //判断成功        assertTrue(succ);    }}
复制代码

可见,Robotium通过一个solo对象来进行各种事件的模拟,代码清晰易懂,并且完全兼容原生AndroidTestFramework

安装部署及稳定性测试

安卓系统最为让人诟病的问题就是碎片化,这点在中国比较明显。大致上,2.3.X 和 4.x 的系统各占半壁江山,此外还存在大量的山寨定制系统。

因此在这推荐两款云端测试工具,Testin和百度云测试。

两个框架测试都很简单,在官网注册账号后上传apk即可,网站会用大量的真机进行安装部署和monkey测试。测试完成后会发送一份测试给注册邮箱。

Testin支持Robotium框架的代码测试,同时上传项目apk和测试apk(相同签名)即可。

Testin地址:http://www.testin.cn/

百度云测试:http://mtc.baidu.com/

其他测试框架

Monkey测试

Android SDK开发包中自带一个monkeyrunner的工具,可用来进行monkey测试。
文档地址:

  • http://developer.android.com/tools/help/monkeyrunner_concepts.html
  • http://developer.android.com/tools/help/monkey.html

Robolectric

一款基于JVM运行的Android测试框架,最大特点就是不需要启动模拟器,因此速度非常快!
目前已支持大部分原生SDK功能的测试,支持Resource,但对于一些特殊硬件上的模拟还存在欠缺。期待进一步的完善
示例代码:

复制代码
// Test class for MyActivity@RunWith(RobolectricTestRunner.class)public class MyActivityTest {  @Test  public void clickingButton_shouldChangeResultsViewText() throws Exception {    Activity activity = Robolectric.buildActivity(MyActivity.class).create().get();    Button pressMeButton = (Button) activity.findViewById(R.id.press_me_button);    TextView results = (TextView) activity.findViewById(R.id.results_text_view);    pressMeButton.performClick();    String resultsText = results.getText().toString();    assertThat(resultsText, equalTo("Testing Android Rocks!"));  }}
复制代码

地址:http://robolectric.org/index.html

Google Espresso

Google于2013年10月开源的一款测试框架。据称在Google内部已通过多个项目的实际验证,并可能在未来加入到默认AndroidSDK中。
设计上接近Robotium,主要用于业务端的模拟行为测试。相较Robotium,具有更为强大的UI元素匹配寻找功能和更快的运行速度。
不过经过本人的实际使用,发现该框架的代码编写相对复杂,远不如Robotium来的轻巧。此外,该框架无法运行在默认AndroidTestFramework中(可认为是升级版),且因刚开源,缺少文档和应用案例等资料,导致测试代码编写效率相对低下,故暂时不予采用。
地址:https://code.google.com/p/android-test-kit/wiki/Espresso

Mockito

一款用于Mock测试的主流框架
地址:https://code.google.com/p/mockito/

  List mockedList = mock(List.class);  when(mockedList.get(0)).thenReturn("first");  System.out.println(mockedList.get(0));
   

总结

如无意外,接下来一段时间内,Android项目会采用以下的方案搭建测试框架:

  • 代码级: AndroidTestFramework + Junit
  • UI业务模拟: Robotium
  • 安装部署: Testin
  • CI: Jenkins

有兴趣的同学也可关注下Robolectric和Espresso两个框架的进展。


参考链接:

android单元测试常用方法:http://blog.csdn.net/henry121212/article/details/7837074

android单元测试例子详解:http://www.360doc.com/content/12/0109/09/7635_178233787.shtml

Android单元测试初探——Instrumentation:http://www.oschina.net/question/54100_27061

如何进行Android单元测试:http://www.cnblogs.com/feisky/archive/2010/07/23/1783826.html

更多相关文章

  1. Android studio中Git的学习和使用心得(二)在Android studio中如何
  2. afinal logoAndroid的快速开发框架 afinal
  3. Android Studio代码调试大全
  4. Android SDK Document 框架导读的翻译和注解[3]
  5. Android 实现闪屏页和右上角的倒计时跳转实例代码
  6. 非常详细的测试unity与android之间的通讯操作
  7. Android电话Phone设计框架介绍
  8. afinal框架之Android视频下载,指定路径

随机推荐

  1. 纪念我开始学习android的文章
  2. android中异步消息的处理机制
  3. 百度强势介入分裂 Android
  4. android 安全讲座第四层 手机Root授权原
  5. 反编译并且修改Android APK包
  6. Android(安卓)监听开机广播
  7. 你的Android不好用,都是因为这几点原因
  8. Android使用AIDL实现进程间的简单通信
  9. OS版本不同造成的一些问题
  10. Android shell 下 busybox,clear,tcpdump、