安卓测试

单元测试TestCase

Android的sdk提供了对项目进行单元测试的功能,开发包的android.test下面便是专门用来单元测试的类。单元测试的作用是通过模拟文本输入和手势输入(如点击操作),从而让app自动执行一系列的操作,这样就能够检查程序是否运行正常。


下面是搭建测试工程的具体步骤:
1、首先当然你得有一个待测试的app工程,最简单的如带有一个编辑框的Hello World工程;
2、其次在ADT中创建测试工程,操作步骤为依次选择菜单“File”——“New”——“Other...”——“Android Test Project”,然后在弹窗中选择待测试的工程,点击Finish按钮完成创建。
打开测试工程的AndroidManifest.xml,会看到里面多了两处配置,截图如下:

第一处配置是instrumentation节点,表示要对哪个工程进行测试,其中android:name属性固定填“android.test.InstrumentationTestRunner”,android:targetPackage属性填待测试的工程包名。
另一处配置是uses-library节点,android:name属性值固定填“android.test.runner”。
3、在测试工程中创建一个TestCase的派生类,该派生类可从ActivityTestCase可继承自ActivityTestCase,也可继承自InstrumentationTestCase。
4、右击测试工程,在右键菜单中依次选择“Run As”——“Android JUint Test”,即可在测试设备上看到单元测试的运行页面。


下面是一个TestCase派生类的代码例子:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import android.os.SystemClock;  
  2. import android.test.InstrumentationTestCase;  
  3. import android.util.Log;  
  4.   
  5. public class Sampletest extends InstrumentationTestCase {  
  6.     private final static String TAG = "Sampletest";  
  7.   
  8.     private MainActivity activity = null;  
  9.     private Button btn = null;  
  10.     private TextView tv = null;  
  11.       
  12.     //初始化设置,初始化页面对象与控件对象  
  13.     @Override    
  14.     protected void setUp()  {  
  15.         try {  
  16.             super.setUp();  
  17.         } catch (Exception e) {  
  18.             e.printStackTrace();  
  19.         }  
  20.         Intent intent = new Intent();  
  21.         intent.setClassName("com.example.test", MainActivity.class.getName());  
  22.         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  23.         activity = (MainActivity) getInstrumentation().startActivitySync(intent);  
  24.         tv = (TextView) activity.findViewById(R.id.tv);  
  25.         btn = (Button) activity.findViewById(R.id.btn);  
  26.     }  
  27.       
  28.     //垃圾清理与资源回收,测试完毕退出页面  
  29.     @Override    
  30.     protected void tearDown()  {  
  31.         activity.finish();  
  32.         try {  
  33.             super.tearDown();  
  34.         } catch (Exception e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.     }  
  38.       
  39.     //活动功能测试,凡是public且以test打头的函数,均会被JUnit测试到  
  40.     public void testActivity() throws Exception {  
  41.         Log.d(TAG, "test the Activity");  
  42.         SystemClock.sleep(1000);//先sleep一会,这时的文字是hello    
  43.         for(int i=0; i<1000; i++) { //点击1000次    
  44.             getInstrumentation().runOnMainSync(new PerformClick(btn));  
  45.         }  
  46.         SystemClock.sleep(2000);//再sleep一会,这时看到的文字是Hello Android  
  47.         Log.d(TAG,  tv.getText().toString());  
  48.         assertEquals("Hello World", tv.getText().toString());  
  49.         //注意,这里做了一个判断,判断当前tv标签控件的文字是不是Hello World,当然不是,所以这句判断是错的!!!!    
  50.     }  
  51.   
  52.     private class PerformClick implements Runnable {  
  53.         Button btn;  
  54.         public PerformClick(Button button) {  
  55.             btn = button;  
  56.         }  
  57.     
  58.         public void run() {  
  59.             btn.performClick();  
  60.         }  
  61.     }  
  62. }  


如果你是在Android Studio上开发,那在创建Android工程时便已生成测试类,默认名称是ApplicationTest.java,测试代码的编写规则同Eclipse,这里就不再赘述。


自动化测试框架Robotium

上面提到的测试代码编写,其实比较繁琐,一般只用于单个页面的测试,所以简单带过不作详述。实际工作中常用的是Robotium这个工具,它是Android官方提供的测试框架,不但方便开发者编写测试代码进行调试,而且也支持在多个页面中跳转测试。


使用Robotium仍然是要一步一步创建测试工程,只不过在测试工程中导入Robotium的jar包,并在TestCase中使用Solo类编写测试代码。Robotium的最新jar包是robotium-solo-5.3.1.jar,下载地址是 http://pan.baidu.com/s/1qXHT9OK


Robotium的代码编写不难,我就直接上官方的demo代码,补充中文注释便一目了然了,代码如下:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. import com.robotium.solo.Solo;  
  2. import com.example.android.notepad.NotesList;  
  3.   
  4. import android.test.ActivityInstrumentationTestCase2;  
  5.   
  6. public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList>{  
  7.   
  8.     private Solo solo;  
  9.   
  10.     public NotePadTest() {  
  11.         super(NotesList.class);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void setUp() throws Exception {  
  16.         //初始化一个Solo对象  
  17.         solo = new Solo(getInstrumentation(), getActivity());  
  18.     }  
  19.   
  20.     @Override  
  21.     public void tearDown() throws Exception {  
  22.         //测试结束要关闭所有打开的页面  
  23.         solo.finishOpenedActivities();  
  24.     }  
  25.   
  26.     //测试添加记录  
  27.     public void testAddNote() throws Exception {  
  28.         //解锁屏幕  
  29.         solo.unlockScreen();  
  30.         //点击菜单项“Add note”  
  31.         solo.clickOnMenuItem("Add note");  
  32.         //声明NoteEditor这个页面已经打开  
  33.         solo.assertCurrentActivity("Expected NoteEditor activity""NoteEditor");   
  34.         //往序号为0的编辑框输入“Note 1”  
  35.         solo.enterText(0"Note 1");  
  36.         //回到上一页  
  37.         solo.goBack();   
  38.         //点击菜单项“Add note”  
  39.         solo.clickOnMenuItem("Add note");  
  40.         //往序号为0的编辑框输入“Note 2”  
  41.         //注意enterText和typeText的区别在于:typeText是模拟键盘输入,  
  42.         //所以typeText的字符串中如果包含“\n”会转为换行符,而enterText只会原样显示字符串“\n”  
  43.         solo.typeText(0"Note 2");  
  44.         //回到上一页  
  45.         solo.goBack();   
  46.         //捕捉屏幕截图并保存到默认路径:Environment.getExternalStorageDirectory()+"Robotium-Screenshots/".  
  47.         solo.takeScreenshot();  
  48.         //检查是否找到“Note 1”和“Note 2”  
  49.         boolean notesFound = solo.searchText("Note 1") && solo.searchText("Note 2");  
  50.         //如果找到则通过测试  
  51.         assertTrue("Note 1 and/or Note 2 are not found", notesFound);   
  52.     }  
  53.       
  54.     public void testEditNote() throws Exception {  
  55.         //点击列表视图的第二项,即进入到该记录的编辑页面  
  56.         solo.clickInList(2);   
  57.         //隐藏软键盘  
  58.         solo.hideSoftKeyboard();  
  59.         //变更屏幕方向为水平方向  
  60.         solo.setActivityOrientation(Solo.LANDSCAPE);  
  61.         //点击菜单项“Edit title”  
  62.         solo.clickOnMenuItem("Edit title");  
  63.         //往序号为0的编辑框追加输入“ test”  
  64.         solo.enterText(0" test");  
  65.         //回到上一页  
  66.         solo.goBack();  
  67.         //设置屏幕方向为垂直方向  
  68.         solo.setActivityOrientation(Solo.PORTRAIT);  
  69.         //使用通配符查找是否存在指定文本  
  70.         boolean noteFound = solo.waitForText("(?i).*?note 1 test");   
  71.         //如果找到则通过测试  
  72.         assertTrue("Note 1 test is not found", noteFound);   
  73.     }  
  74.       
  75.     public void testRemoveNote() throws Exception {  
  76.         //使用通配符查找是否存在包含test的文本  
  77.         solo.clickOnText("(?i).*?test.*");  
  78.         //点击菜单项“Delete”  
  79.         solo.clickOnMenuItem("Delete");  
  80.         //查找是否存在文本“Note 1 test”  
  81.         boolean noteFound = solo.searchText("Note 1 test");  
  82.         //如果没找到则通过测试  
  83.         assertFalse("Note 1 Test is found", noteFound);    
  84.         //长按文本“Note 2”  
  85.         solo.clickLongOnText("Note 2");  
  86.         //在弹出的上下文菜单中点击文本“Delete”  
  87.         solo.clickOnText("Delete");    
  88.         //等待100毫秒后查找是否存在文本“Note 2”  
  89.         noteFound = solo.waitForText("Note 2"1100);  
  90.         //如果没找到则通过测试  
  91.         assertFalse("Note 2 is found", noteFound);    
  92.     }  
  93. }  


功能测试/常用模拟器

ADT和Adnroid Studio都提供了自带的模拟器,用于开发者测试app的页面功能,可是众所周知,自带的模拟器又耗资源、运行又慢,所以实际开发中基本不用自带模拟器。那么调试app的设备主要有下面几种:
1、下载并安装国外模拟器Genymobile,还要在Eclipse中安装Genymobile插件,这样便能在Eclipse中使用Genymobile。但该模拟器搭建环境很繁琐,首先下载前要在它的官网注册,安装时又要指定虚拟机,不够傻瓜。
2、安装国内的模拟器,比如博主一开始用的是夜神模拟器,后来又改用逍遥安卓模拟器。总的来说,国产模拟器不但操作方便,而且比国外模拟器更贴近国人的使用习惯。
3、把真机用数据线插到电脑的usb口,直接使用真机测试app。但这对真机的要求比较高,如果真机的系统版本比较老,那就无法测试高版本上的新特性。


性能测试工具

DDMS

DDMS是ADT自带的测试监控服务,实际开发中一般主要用到它的三个功能:
1、首先当然是LogCat服务,开发者都在该日志窗口查看app运行日志;
2、其次是File Explorer窗口,通过该窗口我们可以往测试设备上传文件,或者下载文件;
3、再次就是检查内存泄漏时用到的Heap窗口,有关内存泄漏的介绍参见《 Android开发笔记(七十五)内存泄漏的处理 》,下面是Heap窗口的内存数据截图:



APT

APT是一个用于app性能测试的Eclipse插件,源码主页在https://code.csdn.net/Tencent/apt/tree/master。
使用的时候,只需把最新的jar包如APT_Eclipse_Plugin_1.1.8.jar复制到Eclipse的plugins目录,然后重启Eclipse即可。在ADT上依次选择菜单“Window”——“Open Perspective”——“Other”——“APT”即可打开APT透视图,即可在该页面查看手机上各进程的cpu和内存使用情况。
不过我这边打开APT后并未看到详细的运行情况,不知咋回事,查看APT的项目主页,发现它最后一次更新时间是2014年12月份,其开发团队后面转去另一个性能测试项目GT了,所以想想还是不必深究APT了。


GT

GT的官网是http://gt.qq.com/。下面是官网对它的介绍:GT(随身调)是APP的随身调测平台,它是直接运行在手机上的“集成调测环境”(IDTE, Integrated Debug Environment)。利用GT,仅凭一部手机,无需连接电脑,您即可对APP进行快速的性能测试(CPU、内存、流量、电量、帧率/流畅度等等)、开发日志的查看、Crash日志查看、网络数据包的抓取、APP内部参数的调试、真机代码耗时统计等。
使用GT要在官网下载GT安装包,如最新版本是GT_2.2.6.4.apk,把该apk包安装到手机上,启动GT后就能对指定app进行性能监控。下面是GT的首页截图:



机型测试网站

app在真机和模拟器上测试通过了,这并不意味着万事大吉,因为Android是个开源的系统,各厂家都可以进行定制修改,所以在A品牌手机上运行正常的app,也许在B品牌手机上就会发生崩溃。可是Android的手机厂家不像ios只有苹果一家,而是百花齐放、千军万马,国内厂家就有华为(mate、荣耀)、小米(小米、红米)、步步高(vivi、oppo)、联想、中兴、酷派、魅族、TCL、HTC等等,国外厂家则有三星、LG、索爱等等,要想在这么多品牌手机上都测试一遍,测试人员都要累趴了。


基于此,现在有多个专业的云测试网站,它们提供了少则一百、多则上万机型的兼容测试服务,开发者只需注册并上传app安装包,即可在一天之内收到多种机型的测试报告,极大方便了我们的测试工作。下面是几个比较大的云测试网站:
TestIn : http://testin.cn/
易测云 : http://www.yiceyun.com/
智测云 : http://www.smarterapps.cn/
百度MTC : http://mtc.baidu.com/
腾讯优测 : http://utest.qq.com/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值