Android单元測试之JUnit
随着近期几年測试方面的工作慢慢火热起来。常常看见有招聘測试project师的招聘信息。在Java中有单元測试这么一个JUnit
方式,Android眼下主要编写的语言是Java,所以在Android开发中也会有那么一个单元測试---JUnit。从Android的开发环境搭建可
以看出来,Android先要在JDK的基础上,然后导入Android自己的SDK开发环境,当然Android的单元測试JUnit是专门測试Android
APP里面的方法性能等。Android最常见的測试----JUnit。Android提供了一系列强大的測试工具,它针对Android的环境。扩展了
业内标准的JUnit測试框架。
虽然你能够使用JUnit測试Androidproject,但Android工具同意你为应用程序的各个方面进行更为复杂的
測试。包含单元层面及框架层面。
一、Android測试环境的主要特征有:
1、能够訪问Android系统对象。
2、Instrumentation框架能够控制和測试应用程序。
3、Android系统经常使用对象的模拟版本号。
4、执行单个test或test suite的工具,带或不带Instrumentation。
5、支持以Eclipse的ADT插件和命令行方式管理Test和Testproject。
二、JUnit核心框架-----Instrumentation框架:
Android測试环境的核心是一个Instrumentation框架,在这个框架下,你的測试应用程序能够精确控制应用程序。使用Instrumentation。你能够在主程序启动之前,创建模拟的系统对象。如Context。控制应用程序的多个生命周期;发送UI事件给应用程序;在执行期间检查程序状态。Instrumentation框架通过将主程序和測试程序执行在同一个进程来实现这些功能。
通过在測试project的manifest文件里加入<instrumentation>元素来指定要測试的应用程序。这个元素的特性指明了要測试的应用程序包名,以及告诉Android怎样执行測试程序。 在Android中,測试程序也是Android程序。因此。它和被測试程序的书写方式有非常多同样的地方。
SDK工具能帮助你同一时候创建主程序project及它的測试project。
你能够通过Eclipse的ADT插件或者命令行来执行Android測试。Eclipse的ADT提供了大量的工具来创建測试用例。执行以及查看结果。
首先,我们来了解一下android的測试类的层次结构:
Testing API
Android提供了基于JUnit測试框架的測试API来书写測试用例和測试程序。
另外,Android还提供了强大的Instrumentation框架。同意測试用例訪问程序的状态及执行时对象。
JUnit TestCase类
继承自JUnit的TestCase,不能使用Instrumentation框架。
但这些类包括訪问系统对象(如Context)的方法。使用Context。你能够浏览资源,文件,数据库等等。基类是AndroidTestCase,一般常见的是它的子类,和特定组件关联。
子类有:
1、ApplicationTestCase——測试整个应用程序的类。它同意你注入一个模拟的Context到应用程序中,在应用程序启动之前初始化測试參数,并在应用程序结束之后销毁之前检查应用程序。
2、ProviderTestCase2——測试单个ContentProvider的类。
由于它要求使用MockContentResolver,并注入一个IsolatedContext。因此Provider的測试是与OS孤立的。
3、ServiceTestCase——測试单个Service的类。你能够注入一个模拟的Context或模拟的Application(或者两者),或者让Android为你提供Context和MockApplication。
Instrumentation TestCase类
继承自JUnit TestCase类,并能够使用Instrumentation框架。用于測试Activity。
使用Instrumentation,Android能够向程序发送事件来自己主动进行UI測试。并能够精确控制Activity的启动,监測Activity生命周期的状态。
基类是InstrumentationTestCase。
它的全部子类都能发送按键或触摸事件给UI。子类还能够注入一个模拟的Intent。
子类有:
1、 ActivityTestCase——Activity測试类的基类。
2、 SingleLaunchActivityTestCase——測试单个Activity的类。它能触发一次setup()和tearDown()。而不是每一个方法调用时都触发。假设你的測试方法都是针对同一个Activity的话。那就使用它吧。
3、 SyncBaseInstrumentation——測试Content Provider同步性的类。
它使用Instrumentation在启动測试同步性之前取消已经存在的同步对象。
4、ActivityUnitTestCase——对单个Activity进行单一測试的类。
使用它。你能够注入模拟的Context或Application,或者两者。它用于对Activity进行单元測试。
不同于其他的Instrumentation类,这个測试类不能注入模拟的Intent。
5、 ActivityInstrumentationTestCase2——在正常的系统环境中測试单个Activity的类。
你不能注入一个模拟的Context。但你能够注入一个模拟的Intent。
另外,你还能够在UI线程(应用程序的主线程)执行測试方法。而且能够给应用程序UI发送按键及触摸事件。
三、Instrumentation框架的測试使用方法
Instrumentation和Activity有点类似,仅仅只是Activity是须要一个界面的。而Instrumentation并非这种,我们能够将它理解为一种没有图形界面的。具有启动能力的,用于监控其它类(用Target Package声明)的工具类。
以下通过一个简单的样例来解说Instrumentation的基本測试方法。
1.首先建立一个Android project,类名为Sample,代码例如以下:
public class Sample extends Activity {
private TextView myText = null;
private Button button = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myText = (TextView) findViewById(R.id.text1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
myText.setText("Hello Android");
}
});
}
public int add(int i, int j) {
return (i + j);
}
}
这个程序的功能比較简单。点击button之后,TextView的内容由Hello变为Hello Android.同一时候。在这个类中。我还写了一个简单的add方法。没有被调用,仅供測试而已。
2. 在src目录中加入一个測试包。在測试包中加入一个測试类SampleTest
測试类的代码例如以下:
public class SampleTest extends InstrumentationTestCase {
private Sample sample = null;
private Button button = null;
private TextView text = null;
/*
* 初始设置
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() {
try {
super.setUp();
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent();
intent.setClassName("com.hustophone.sample", Sample.class.getName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sample = (Sample) getInstrumentation().startActivitySync(intent);
text = (TextView) sample.findViewById(R.id.text1);
button = (Button) sample.findViewById(R.id.button1);
}
/*
* 垃圾清理与资源回收
* @see android.test.InstrumentationTestCase#tearDown()
*/
@Override
protected void tearDown() {
sample.finish();
try {
super.tearDown();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 活动功能測试
*/
public void testActivity() throws Exception {
Log.v("testActivity", "test the Activity");
SystemClock.sleep(1500);
getInstrumentation().runOnMainSync(new PerformClick(button));
SystemClock.sleep(3000);
assertEquals("Hello Android", text.getText().toString());
}
/*
* 模拟button点击的接口
*/
private class PerformClick implements Runnable {
Button btn;
public PerformClick(Button button) {
btn = button;
}
public void run() {
btn.performClick();
}
}
/*
* 測试类中的方法
*/
public void testAdd() throws Exception{
String tag = "testAdd";
Log.v(tag, "test the method");
int test = sample.add(1, 1);
assertEquals(2, test);
}
}
以下来简单解说一下代码:
setUp()和tearDown()都是受保护的方法。通过继承能够覆写这些方法。
在android Developer中有例如以下的解释
protected void setUp ()
Since: API Level 3
Sets up the fixture, for example, open a network connection. This method is called before a test is executed.
protected void tearDown ()
Since: API Level 3
Make sure all resources are cleaned up and garbage collected before moving on to the next test. Subclasses that override this method should make sure they call super.tearDown() at the end of the overriding method.
setUp ()用来初始设置。如启动一个Activity,初始化资源等。
tearDown ()则用来垃圾清理与资源回收。
在testActivity()这个測试方法中。我模拟了一个button点击事件。然后来推断程序是否依照预期的运行。在这里PerformClick这种方法继承了Runnable接口,通过新的线程来运行模拟事件,之所以这么做。是由于假设直接在UI线程中运行可能会阻滞UI线程。
2.要想正确地运行測试,还须要改动AndroidManifest.xml这个文件.
<!--用于引入測试库-->
<uses-library android:name="android.test.runner" />
<activity android:name=".Sample" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-sdk android:minSdkVersion="3" />
<!--表示被測试的目标包与instrumentation的名称。-->
<instrumentation android:targetPackage="com.hustophone.sample" android:name="android.test.InstrumentationTestRunner" />
经过以上步骤,以下能够開始測试了。測试方法也有以下几种,以下介绍两个经常使用的方法:
(1) 用Eclipse集成的JUnit工具
在Eclipse中选择projectSample,单击右键。在Run as子菜单选项中选择Android JUnit Test
同一时候能够通过LogCat工具查看信息
(2) 通过模拟器执行单元測试
点击模拟器界面的Dev Tools菜单
再点击Instrumentation选项。进入Instrumentation菜单
这里有一个InstrumentationTestRunner,它是測试的入口。点击这个选项,就能够自己主动执行我们的測试代码。下面为执行结果:
button点击前
button点击后
至此,一个简单的測试过程结束了。当然。android的測试内容还有非常多,也有比較复杂的,我会在以后的学习过程中继续分享我的体会。
好了。今天就到这里吧!
Android单元測试之JUnit的更多相关文章
- Java单元測试工具JUnit 5新特性一览
Java单元測试工具JUnit 5新特性一览 作者:chszs,未经博主同意不得转载. 经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs JUnit是最流行的开源 ...
- 【Android进阶】Junit单元測试环境搭建以及简单有用
单元測试的目的 首先.Junit单元測试要实现的功能,就是用来測试写好的方法是否可以正确的运行,一般多用于对业务方法的測试. 单元測试的环境配置 1.在AndroidManifest清单文件的Appl ...
- Android studio及eclipse中的junit单元測试
转载请标明出处:http://blog.csdn.net/nmyangmo/article/details/51179106 前一段时间有人问我单元測试的相关内容,我稍作总结做日志例如以下: 由于我接 ...
- (4.5.4)Android測试TestCase单元(Unit test)測试和instrumentationCase单元測试
Android单元和instrumentation单元測试 Developing Android unit and instrumentation tests Android的单元測试是基于JUnit ...
- Android 进行单元測试难在哪-part3
原文链接 : HOW TO MAKE OUR ANDROID APPS UNIT TESTABLE (PT. 1) 原文作者 : Matthew Dupree 译文出自 : 开发技术前线 www.de ...
- Android下的单元測试
android下的单元測试 在AndroidManifest.xml文件里配置下面信息: 在manifest节点下加入: <!-- 指定測试信息和要測试的包 --> <instrum ...
- 菜鸟学Java(二十一)——怎样更好的进行单元測试——JUnit
測试在软件生命周期中的重要性,不用我多说想必大家也都很清楚.软件測试有许多分类,从測试的方法上可分为:黑盒測试.白盒測试.静态測试.动态測试等:从软件开发的过程分为:单元測试.集成測试.确认測试.验收 ...
- 谈谈单元測试之(二):測试工具 JUnit 3
前言 上一篇文章<为什么要进行烦人的单元測试?>讨论了一下现阶段软件开发中,程序猿们測试情况的现状.这篇文章中,我打算介绍一下单元測试的工具(插件).而且推荐大家以后在开发中,真正的用上单 ...
- 在Eclipse中使用JUnit4进行单元測试(0基础篇)
本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,须要写成千上万个方法或函数,这些函数的功能可能 ...
随机推荐
- Java菜鸟学习笔记--数组篇(三):二维数组
定义 //1.二维数组的定义 //2.二维数组的内存空间 //3.不规则数组 package me.array; public class Array2Demo{ public static void ...
- 记事本写hello world_Java
1 新建记事本,重命名为hello.java 2 打开hello.java,编辑并保存 class Hello { public static void main(String[] args) { S ...
- IOS 下雪动画
#define SNOW_IMAGENAME @"snow" #define IMAGE_X arc4random()%(int)Main_Screen_Width #define ...
- Html、CSS、JavaScript 实时效果在线编辑器 - 学习的好工具,算不算?!
关于 二维码 与 NFC 之间的出身贫贱说 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 ...
- 【考虑周全+数学变形】【11月赛】Is it a fantastic matrix?
Is it a fantastic matrix? Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/ ...
- MVC 笔记(二)
HttpUtility.HtmlEncode来预处理用户输入,这能阻止用户向视图中用链接注入js代码或html标记 .[Required]:非空验证 .[StringLength(**)]:设置字符的 ...
- iOS之短信认证
短信验证 现在很多的短信验证平台,我们比较常用的有移动开发者服务平台 根据短信验证文档来集成 1. 找到iOS短信验证的集成开发文档 2. 下载SDK和Demo目录结构 3. 运行Demo 4. 写 ...
- (原)android的JNI中使用C++的类
android的JNI代码中可以调用C++的类,但是不能直接调用,要加上一个类似于接口的java类,这个类内部调用C++的类.实际上和接口类直接调用C++中的函数差不多,只是稍微复杂了一点. 1. 写 ...
- [转]MFC 加载其他的应用程序
三个SDK函数 winexec, shellexecute,createprocess可以使用.WinExec 最简单,两个参数,前一个指定路径,后一个指定显示方式.后一个参数值得说一下,比如泥用 S ...
- oracle使用还原段的目的和还原数据的管理方法及还原段的类型
一.引入还原段主要有3个目的: 1.事务回滚:主要是针对rollback语句起作用 2.事务恢复:非正常关闭数据库即非保留事务级关闭数据库(abort.immediate)或者数据库instance崩 ...