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 我们在编写大型程序的时候,须要写成千上万个方法或函数,这些函数的功能可能 ...
随机推荐
- 二分求解 三角形 stl的应用 涉及范围的二分查找可以先求上界再算下界,结果即上界减下界
二分 Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Description You ...
- 树的直径 poj 2631
树的直径:从随意一点出发,BFS找到最远的距离,然后在从该点出发BFS找到最远的距离 #include <iostream> #include <algorithm> #inc ...
- 从Android Handler内部类到WeakReference的知识关联
Handler: 普通使用方法: Handler用于处理和从队列MessageQueue中得到Message.一般我们要重写Handler的handleMessage(Message msg){}方法 ...
- 去除input在谷歌下的focus效果
input:focus{outline: -webkit-focus-ring-color auto 0;}
- oracle spoof用法
关于SPOOL(SPOOL是SQLPLUS的命令,不是SQL语法里面的东西.) 对于SPOOL数据的SQL,最好要自己定义格式,以方便程序直接导入,SQL语句如: select taskindex|| ...
- Json.Net序列化和反序列化设置
首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.创建一 ...
- java数据导出成 EXCEL
/** * * @param out 输出流 * @param maplist 数据 * @param title 标题 * @param headers 表头 * @param keys 表头对应的 ...
- A - Next_permutation
首先介绍一下next_permutation函数的用途! 按照STL文档的描述,next_permutation函数将按字母表顺序生成给定序列的下一个较大的排列,直到整个序列为降序为止. prev_p ...
- STM32的例程GPIO的汇编指令初探
任务一:寻找main函数的汇编指令集 任务二:寻找main函数中的SystemClock_Config函数的汇编指令集 寻找main函数的汇编指令集 运行例程中GPIO工程时,总会加载startup_ ...
- C#传递参数大集合
方法的参数是个值得特别注意的地方.方法的参数传递有四种类型:传值(by value),传址(by reference),输出参数(by output),数组参数(by array).传值参数无需额外的 ...