创建测试工程:
测试工程通常都不是独立存在的,而是依赖于某个现有工程的,一般比较常见的做法是在现有工程下新建一个test文件夹,测试工程就存放在这里。
此处以BroadcastBestPractice这个项目为例 这里是项目
在Eclipse的导航栏中点击File->New->Other,会打开一个对话框。展开Android目录,在里面选中AndroidTestProject。
点击Next后会弹出创建Android测试工程的对话框,在这里我们可以输入测试工程的名字,并选择测试工程的路径
选择测试哪一个项目
点击Finish即可完成
此时观察测试工程中的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastbestpractice.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.broadcastbestpractice" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<span style="color:#ff0000;"><uses-library android:name="android.test.runner" /></span>
</application>
</manifest>
<instrumentation>和<uses-library>标签是自动生成的,表示这是一个测试工程
在<instrumentation>标签中还通过android:targetPackage属性指定了测试目标的包名
下面进行单元测试
单元测试是指对软件中最小的功能模块进行测试,如果软件中的每一个单元都能通过测试,说明代码的健壮性就已经非常好了
BroadcaseBestPractice项目中有一个ActivityCollector类,主要用于对所有的Activity进行管理
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity) {
activities.add(activity);
}
public static void removeActivity(Activity activity) {
activities.remove(activity);
}
public static void finishAll() {
for (Activity activity : activities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
我们来测试这个类
首先在BroadcastBestPracticeTest项目中新建一个ActivityCollectorTest类,并让它继承自AndroidTestCase,并重写setUp()和tearDown()方法
public class ActivityCollectorTest extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
其中setUp()方法会在所有的测试用例执行之前调用,可以在这里进行一些初始化操作。
tearDown()方法会在所有的测试用例执行之后调用,可以在这里进行一些资源释放的操作。
一般来说,编写测试用例,只需要定义一个以test开头的方法,测试框架就会自动调用这个方法了
然后我们在方法中可以通过断言(assert)的形式来期望一个运行结果,再和实际的运行结果进行对比
比如测试ActivityCollector中的addActivity()方法:
public class ActivityCollectorTest extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
}
public void testAddActivity() {
assertEquals(0, ActivityCollector.activities.size());
LoginActivity loginActivity = new LoginActivity();
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
这里我们添加了一个testAddActivity()方法
使用assertEquals()方法进行断言
右击测试工程->Run As->Android JUnit Test 来运行这个测试用例
测试结果通过
我们再添加一些特殊情况下的断言
public class ActivityCollectorTest extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
}
public void testAddActivity() {
assertEquals(0, ActivityCollector.activities.size());
LoginActivity loginActivity = new LoginActivity();
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
ActivityCollector.addActivity(loginActivity);
assertEquals(1, ActivityCollector.activities.size());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
这里添加了两次相同活动的实例
用于测试ActivityCollector是否有能力过滤掉重复的数据
很遗憾,测试用例并没有通过
提示我们期望结果是1,但实际结果却是2
可以发现addActivity()方法中的代码是不够健壮的
修改ActivityCollector中的代码
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity) {
if (!activities.contains(activity)) {
activities.add(activity);
}
}
public static void removeActivity(Activity activity) {
activities.remove(activity);
}
public static void finishAll() {
for (Activity activity : activities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
再跑一遍测试用例
成功通过