Android开发笔记(一百一十三)测试工具

单元测试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派生类的代码例子:

import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.util.Log;

public class Sampletest extends InstrumentationTestCase {
	private final static String TAG = "Sampletest";

    private MainActivity activity = null;
    private Button btn = null;
    private TextView tv = null;

    //初始化设置,初始化页面对象与控件对象
    @Override
    protected void setUp()  {
        try {
            super.setUp();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Intent intent = new Intent();
        intent.setClassName("com.example.test", MainActivity.class.getName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        activity = (MainActivity) getInstrumentation().startActivitySync(intent);
        tv = (TextView) activity.findViewById(R.id.tv);
        btn = (Button) activity.findViewById(R.id.btn);
    }

    //垃圾清理与资源回收,测试完毕退出页面
    @Override
    protected void tearDown()  {
        activity.finish();
        try {
            super.tearDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //活动功能测试,凡是public且以test打头的函数,均会被JUnit测试到
    public void testActivity() throws Exception {
        Log.d(TAG, "test the Activity");
        SystemClock.sleep(1000);//先sleep一会,这时的文字是hello
        for(int i=0; i<1000; i++) { //点击1000次
            getInstrumentation().runOnMainSync(new PerformClick(btn));
        }
        SystemClock.sleep(2000);//再sleep一会,这时看到的文字是Hello Android
        Log.d(TAG,  tv.getText().toString());
        assertEquals("Hello World", tv.getText().toString());
        //注意,这里做了一个判断,判断当前tv标签控件的文字是不是Hello World,当然不是,所以这句判断是错的!!!!
    }

    private class PerformClick implements Runnable {
        Button btn;
        public PerformClick(Button button) {
            btn = button;
        }

        public void run() {
            btn.performClick();
        }
    }
}

如果你是在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代码,补充中文注释便一目了然了,代码如下:

import com.robotium.solo.Solo;
import com.example.android.notepad.NotesList;

import android.test.ActivityInstrumentationTestCase2;

public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList>{

	private Solo solo;

	public NotePadTest() {
		super(NotesList.class);
	}

	@Override
	public void setUp() throws Exception {
		//初始化一个Solo对象
		solo = new Solo(getInstrumentation(), getActivity());
	}

	@Override
	public void tearDown() throws Exception {
		//测试结束要关闭所有打开的页面
		solo.finishOpenedActivities();
	}

	//测试添加记录
	public void testAddNote() throws Exception {
		//解锁屏幕
		solo.unlockScreen();
		//点击菜单项“Add note”
		solo.clickOnMenuItem("Add note");
		//声明NoteEditor这个页面已经打开
		solo.assertCurrentActivity("Expected NoteEditor activity", "NoteEditor");
		//往序号为0的编辑框输入“Note 1”
		solo.enterText(0, "Note 1");
		//回到上一页
		solo.goBack();
		//点击菜单项“Add note”
		solo.clickOnMenuItem("Add note");
		//往序号为0的编辑框输入“Note 2”
		//注意enterText和typeText的区别在于:typeText是模拟键盘输入,
		//所以typeText的字符串中如果包含“\n”会转为换行符,而enterText只会原样显示字符串“\n”
		solo.typeText(0, "Note 2");
		//回到上一页
		solo.goBack();
		//捕捉屏幕截图并保存到默认路径:Environment.getExternalStorageDirectory()+"Robotium-Screenshots/".
		solo.takeScreenshot();
		//检查是否找到“Note 1”和“Note 2”
		boolean notesFound = solo.searchText("Note 1") && solo.searchText("Note 2");
		//如果找到则通过测试
		assertTrue("Note 1 and/or Note 2 are not found", notesFound);
	}

	public void testEditNote() throws Exception {
		//点击列表视图的第二项,即进入到该记录的编辑页面
		solo.clickInList(2);
		//隐藏软键盘
		solo.hideSoftKeyboard();
		//变更屏幕方向为水平方向
		solo.setActivityOrientation(Solo.LANDSCAPE);
		//点击菜单项“Edit title”
		solo.clickOnMenuItem("Edit title");
		//往序号为0的编辑框追加输入“ test”
		solo.enterText(0, " test");
		//回到上一页
		solo.goBack();
		//设置屏幕方向为垂直方向
		solo.setActivityOrientation(Solo.PORTRAIT);
		//使用通配符查找是否存在指定文本
		boolean noteFound = solo.waitForText("(?i).*?note 1 test");
		//如果找到则通过测试
		assertTrue("Note 1 test is not found", noteFound);
	}

	public void testRemoveNote() throws Exception {
		//使用通配符查找是否存在包含test的文本
		solo.clickOnText("(?i).*?test.*");
		//点击菜单项“Delete”
		solo.clickOnMenuItem("Delete");
		//查找是否存在文本“Note 1 test”
		boolean noteFound = solo.searchText("Note 1 test");
		//如果没找到则通过测试
		assertFalse("Note 1 Test is found", noteFound);
		//长按文本“Note 2”
		solo.clickLongOnText("Note 2");
		//在弹出的上下文菜单中点击文本“Delete”
		solo.clickOnText("Delete");
		//等待100毫秒后查找是否存在文本“Note 2”
		noteFound = solo.waitForText("Note 2", 1, 100);
		//如果没找到则通过测试
		assertFalse("Note 2 is found", noteFound);
	}
}

功能测试/常用模拟器

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/

点此查看Android开发笔记的完整目录

时间: 2024-10-25 09:17:16

Android开发笔记(一百一十三)测试工具的相关文章

Android开发笔记(一百一十)使用http框架上传文件

HTTP上传 与文件下载相比,文件上传的场合不是很多,通常用于上传用户头像.朋友圈发布图片/视频动态等等,而且上传文件需要服务器配合,所以容易被app开发者忽略.就上传的形式来说,app一般采用http上传文件,很少用ftp上传文件. HttpURLConnection上传 很可惜Android没有提供专门的文件上传工具类,所以我们要自己写代码实现上传功能了.其实也不难,一样是按照普通网络访问的POST流程,只是要采用"multipart/form-data"方式来分段传输.另外文件上

【转】Android开发笔记(序)写在前面的目录

原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入门上:其次是想拾缺补漏,写写虽然小众却又用得着的东西:另外就是想以实用为主,不求大而全,但求小而精:还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来.个人的经

Android开发笔记(一百零八)智能语音

智能语音技术 如今越来越多的app用到了语音播报功能,例如地图导航.天气预报.文字阅读.口语训练等等.语音技术主要分两块,一块是语音转文字,即语音识别:另一块是文字转语音,即语音合成. 对中文来说,和语音播报相关的一个技术是汉字转拼音,想想看,拼音本身就是音节拼读的标记,每个音节对应一段音频,那么一句的拼音便能用一连串的音频流合成而来.汉字转拼音的说明参见<Android开发笔记(八十三)多语言支持>. 语音合成通常也简称为TTS,即TextToSpeech(从文本到语言).语音合成技术把文字

Android开发笔记(一百一十二)开发工具

Eclipse/ADT ADT是Google在Eclipse基础上封装了Android开发工具的环境,最新版本是2014年7月2日发布的adt-bundle-windows-x86_64-20140702,之后Google推出自己的开发环境Android Studio,就不再更新ADT了.不过基于Eclipse的广泛使用,当前还是有不少app使用ADT进行开发. 在Eclipse上安装插件的步骤如下:依次选择菜单"Help"--"Install New Software...

Android开发笔记(一百一十六)网络学习资源

知名网站 本系列的开发笔记,对Android开发来说只是沧海一瓢,还有更多的技术等待我们去汲取.下面列出几个常用的开发网站,供初学者上路: 首先当然是国内首屈一指的技术网站csdn啦,csdn提供了众多频道,包括博客.论坛.下载.问答等等,其中博客专栏提供了最新的技术文章,值得推荐.csdn博客专栏的地址是 http://blog.csdn.net/column.html 下面是csdn博客专栏的网页截图: 其次是国外有名的开源网站GitHub,这里有众多的开源项目源码,是开发者分享代码的乐园.

Android开发笔记(一百一十一)聊天室中的Socket通信

Socket通信 基本概念 对于程序开发来说,网络通信的基础就是Socket,但因为是基础,所以用起来不容易,今天我们就来谈谈Socket通信.计算机网络有个大名鼎鼎的TCP/IP协议,普通用户在电脑上设置本地连接的ip时,便经常看到下图的弹窗,注意红框部分已经很好地描述了TCP/IP协议的作用. TCP/IP是个协议组,它分为三个层次:网络层.传输层和应用层: 网络层包括:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 传输层包括:TCP协议.UDP协议. 应用层包括:HT

Android开发笔记(一百一十九)工具栏ToolBar

Toolbar 在前面的博文<Android开发笔记(二十)顶部导航栏>中,我们学习了ActionBar的用法,可是ActionBar着实是不怎么好用,比如文字风格不能定制.图标不能定制,而且还存在低版本的兼容性问题,所以实际开发中大家还是不倾向使用ActionBar.为此,Android提供了加强版的工具栏控件即Toolbar,因为Toolbar继承自ViewGroup,而且可在布局文件中像其它布局视图一样使用,所以灵活性大大的提高了.既然Android都与时俱进了,那我们也不能落后,现在就

Android开发笔记(一百一十八)自定义悬浮窗

WindowManager 在前面<Android开发笔记(六十六)自定义对话框>中,我们提到每个页面都是一个Window窗口,许多的Window对象需要一个管家来打理,这个管家我们称之为WindowManager窗口管理.在手机屏幕上新增或删除页面窗口,都可以归结为WindowManager的操作,下面是该管理类的常用方法说明: getDefaultDisplay : 获取默认的显示屏信息.通常用该方法获取屏幕分辨率,详情参见<Android开发笔记(三)屏幕分辨率>. addV

Android开发笔记(一百一十七)app省电方略

电源管理PowerManager PowerManager是Android的电源管理类,用于管理电源操作如睡眠.唤醒.重启以及调节屏幕亮度等等. PowerManager的对象从系统服务POWER_SERVICE中获取,它的主要方法如下: goToSleep : 睡眠,即锁屏. wakeUp : 唤醒,即解锁. reboot : 重启. 另有下列几个隐藏的方法: getMinimumScreenBrightnessSetting : 获取屏幕亮度的最小值. getMaximumScreenBri