Android ActivityUnitTestCase

對於Android 單元測試來說, 若滿足以下測試條件, 可選用 ActivityUnitTestCase 來測試

(1) 針對單一Activity 測試, 不涉及其他Activity交互作用.
如startActivityForResult 的返回結果做測試.
(2) 對UI進行自動化測試

(祖父類別 InstrumentationTestCase 參考資料: Android InstrumentationTestCase)

ActivityUnitTestCase 運用範例

一個Activity中含有一個EditText, TextView, Button

EditText : 使用者輸入框
TextView : 呈現使用者輸入框的內容
Button : 點擊Button , 將EditText的內容呈現在TextView

Step 1: 建立測試檔 MainActivityTest extends ActivityUnitTest

使用 Ctrl + Shift + T 建立測試檔, 並選擇 subclass 為 ActivityUnitTest
位置儲存於 /src/androidTest/java/ package_path /

Step 2: 初始化

建立測試元件

1
2
3
4
5
6
private Intent mStartIntent;
MainActivity mMainActivity;

private Button mTestButton;
private EditText mEditText;
private TextView mTextView;

建立Constructor

1
2
3
public MainActivityTest() {
super(MainActivity.class);
}

當每項測試前, 都會將測試元件初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
protected void setUp() throws Exception {
super.setUp();

mStartIntent = new Intent(Intent.ACTION_MAIN);
mMainActivity = startActivity(mStartIntent, null, null);
assertNotNull(mMainActivity);

mTestButton = (Button) mMainActivity.findViewById(R.id.test_bt);
assertNotNull(mTestButton);

mEditText = (EditText) mMainActivity.findViewById(R.id.enter);
assertNotNull(mEditText);

mTextView = (TextView) mMainActivity.findViewById(R.id.show_text);
assertNotNull(mTextView);
}

Step 3: 測試預設值

1
2
3
4
5
6
7
8
9
10
@UiThreadTest
public void testInitialization() {
String sourceText = null;
String targetText = null;

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();
assertEquals("", sourceText);
assertEquals("Enter..", targetText);
}

由於在 res/layout/activity_main.xml 中 EditText 和 TextView 的初始設定為

activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<EditText
android:id="@+id/enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>

<TextView
android:id="@+id/show_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/enter"
android:text="Enter..."
android:layout_centerHorizontal="true"/>

所以測試項 assertEquals(“Enter..”, targetText); 會無法通過測試 (少了一個點號)

錯誤訊息如下

Step 4: 測試未點擊 Test Button 的情況

1
2
3
4
5
6
7
8
9
10
11
12
13
@UiThreadTest
public void testNotChanged() {
String sourceText = null;
String targetText = null;

mEditText.setText("Not Click Test Button");

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();

assertEquals("Not Click Test Button", sourceText);
assertEquals(sourceText, targetText);
}

雖然EditText內容以被更改, 但還未點擊 Test Button 時, TextView 的內容不會被更改, 所以測試項目 assertEquals(sourceText, targetText) 會無法通過測試.

錯誤訊息如下

Step 5: 測試點擊 Test Button 的情況

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@UiThreadTest
public void testShowText() {
String sourceText = null;
String targetText = null;

mEditText.setText("Click Test Button");
mTestButton.performClick();

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();
assertEquals("Click Test Button", sourceText);
assertEquals("Click Test Button", targetText);
assertEquals(sourceText, targetText);
}

點擊 Test Button後, TextView 的內容會更改為EditText內容

所以此測試項為 Pass

Source Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class MainActivityTest extends ActivityUnitTestCase<MainActivity> {

private Intent mStartIntent;
MainActivity mMainActivity;

private Button mTestButton;
private EditText mEditText;
private TextView mTextView;

public MainActivityTest() {
super(MainActivity.class);
}

@Override
protected void setUp() throws Exception {
super.setUp();

mStartIntent = new Intent(Intent.ACTION_MAIN);
mMainActivity = startActivity(mStartIntent, null, null);
assertNotNull(mMainActivity);

mTestButton = (Button) mMainActivity.findViewById(R.id.test_bt);
assertNotNull(mTestButton);

mEditText = (EditText) mMainActivity.findViewById(R.id.enter);
assertNotNull(mEditText);

mTextView = (TextView) mMainActivity.findViewById(R.id.show_text);
assertNotNull(mTextView);
}

@UiThreadTest
public void testInitialization() {
String sourceText = null;
String targetText = null;

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();
assertEquals("", sourceText);
assertEquals("Enter..", targetText);
}

@UiThreadTest
public void testNotChanged() {
String sourceText = null;
String targetText = null;

mEditText.setText("Not Click Test Button");

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();

assertEquals("Not Click Test Button", sourceText);
assertEquals(sourceText, targetText);
}

@UiThreadTest
public void testShowText() {
String sourceText = null;
String targetText = null;

mEditText.setText("Click Test Button");
mTestButton.performClick();

sourceText = mEditText.getText().toString();
targetText = mTextView.getText().toString();
assertEquals("Click Test Button", sourceText);
assertEquals("Click Test Button", targetText);
assertEquals(sourceText, targetText);
}
}

ps: @UiThreadTest 的順序會根據命名來決定順序

(請參考 Android SingleLaunchActivityTestCase - Step 6)

作者

Nick Lin

發表於

2016-07-28

更新於

2023-01-18

許可協議


評論