Robotium的測試類ActivityInstrumentationTestCase2是繼承于Junit3的TestCase類,所以并沒有提供Junit4的特性.如網(wǎng)上總結(jié)說的
不能通過annotate的方式來識別子類的新特征,如不能實現(xiàn)@beforeclass,@afterclass等特征。只能通過寫setup和teardown,
TestCase只能以test開頭進行測試case書寫。
那么有時我們并不想每次開始/完成一個case的時候都做一些重復的動作,也就是要實現(xiàn)Junit4的@beforeclass和@afterclass,該怎么辦呢?
以SDK自帶的Notepad測試用例作為例子,假如現(xiàn)在我們需要實現(xiàn)兩個測試用例
testAddNoteCNTittle:創(chuàng)建一個中文標題的筆記
testAddNoteEngTitle:創(chuàng)建一個英文標題的筆記
根據(jù)實例提供的代碼,在setup里面會初始化solo而在teardown里面會關(guān)閉所有打開的activities,也就是說每執(zhí)行一個case都會重新初始化一次solo和關(guān)閉所有的activities:
@Override
public void setUp() throws Exception {
//setUp() is run before a test case is started.
//This is where the solo object is created.
super.setUp();
this.activity = this.getActivity();
this.solo = new Solo(getInstrumentation(), getActivity());
}
@Override
public void tearDown() throws Exception {
//tearDown() is run after a test case has finished.
//finishOpenedActivities() will finish all the activities that have been opened during the test execution.
solo.finishOpenedActivities();
}
@Override public void setUp() throws Exception { //setUp() is run before a test case is started. //This is where the solo object is created. super.setUp(); this.activity = this.getActivity(); this.solo = new Solo(getInstrumentation(), getActivity()); } @Override public void tearDown() throws Exception { //tearDown() is run after a test case has finished. //finishOpenedActivities() will finish all the activities that have been opened during the test execution. solo.finishOpenedActivities(); }
但事實上我們在這個腳本只是去創(chuàng)建兩個Note,并不需要每執(zhí)行完一個case都要去初始化solo和關(guān)閉所有activities。google后沒有發(fā)現(xiàn)有現(xiàn)成的取代@beforeclass和@aferclass的方法。
以下本人的實現(xiàn)方法
<pre name="code" class="java">package com.example.android.notepad.test;
import com.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
import android.app.Activity;
@SuppressWarnings("rawtypes")
public class TCCreateNote extends ActivityInstrumentationTestCase2{
private static Solo solo = null;
public Activity activity;
<span style="white-space:pre"> </span>private static final int NUMBER_TOTAL_CASES = 2;
private static int run = 0;
private static Class<?> launchActivityClass;
//對應re-sign.jar生成出來的信息框里的兩個值
private static String mainActiviy = "com.example.android.notepad.NotesList";
private static String packageName = "com.example.android.notepad";
static {
try {
launchActivityClass = Class.forName(mainActiviy);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
public TCCreateNote() {
super(packageName, launchActivityClass);
}
@Override
public void setUp() throws Exception {
//setUp() is run before a test case is started.
//This is where the solo object is created.
super.setUp();
<span style="white-space:pre"> </span>//The variable solo has to be static, since every time after a case's finished, this class TCCreateNote would be re-instantiated
// which would lead to soto to re-instantiated to be null if it's not set as static
if(solo == null) {
TCCreateNote.solo = new Solo(getInstrumentation(), getActivity());
}
}
@Override
public void tearDown() throws Exception {
//Check whether it's the last case executed.
run += countTestCases();
if(run >= NUMBER_TOTAL_CASES) {
solo.finishOpenedActivities();
}
}
public void testAddNoteCNTitle() throws Exception {
solo.clickOnMenuItem("Add note");
solo.enterText(0, "中文標簽筆記");
solo.clickOnMenuItem("Save");
solo.clickInList(0);
solo.clearEditText(0);
solo.enterText(0, "Text 1");
solo.clickOnMenuItem("Save");
solo.assertCurrentActivity("Expected NotesList Activity", "NotesList");
solo.clickLongOnText("中文標簽筆記");
solo.clickOnText("Delete");
}
public void testAddNoteEngTitle() throws Exception {
solo.clickOnMenuItem("Add note");
solo.enterText(0, "English Title Note");
solo.clickOnMenuItem("Save");
solo.clickInList(0);
solo.clearEditText(0);
solo.enterText(0, "Text 1");
solo.clickOnMenuItem("Save");
solo.assertCurrentActivity("Expected NotesList Activity", "NotesList");
solo.clickLongOnText("English Title Note");
solo.clickOnText("Delete");
}
}