什麼是 JUnit ?
JUnit是採用測試驅動開發的方式,也就是說在開發前先寫好測試代碼,主要用來說明被測試的代碼會被如何使用,錯誤處理等;然後開始寫代碼,並在測試代碼中逐步測試這些代碼,直到最後在測試代碼中完全通過。
現簡要說JUnit的4大功能
管理測試案例。修改了哪些代碼,這些代碼的修改會對哪些部分有影響,通過JUnit將這次的修改做個完整測試。這也就JUnit中所謂的TestSuite。
定義測試代碼。這也就是JUnit中所謂的TestCase,根據原始碼的測試需要定義每個TestCase,並將TestCase添加到相應的TestSuite方便管理。
定義測試環境。在TestCase測試前會先調用“環境”配置,在測試中使用,當然也可以在測試案例中直接定義測試環境。
檢測測試結果。對於每種正常、異常情況下的測試,運行結果是什麼、結果是否是我們預期的等都需要有個明確的定義,JUnit在這方面提供了強大的功能。
以上部分與我們平常使用IDE調試的過程是完全一樣的,只不過是增加了測試案例管理、測試結果檢測等功能,提高了單元的效率,保證了單元測試的完整性,明確了單元測試的目標。
一個 JUnit 測試包含以下元素:
開發代碼部分 測試代碼部分 測試載入器部分
待測試類別 A 通過擴充 TestCase 或者構造 TestSuit 方法
編寫測試類別 B 一個測試回合器(TestRunner)R,可以選擇圖形介面或文本介面
操作步驟:
將 B 通過命令列方式或圖形介面選擇方式傳遞給 R,R 自動運行測試,並顯示結果。
首先看下junit測試類別庫和android中單元測試類庫:
SDK 功能說明
junit.framework JUnit測試架構
junit.runner 工具 + 生產力類支援JUnit測試架構
android.test Android 對JUnit測試架構的擴充包
android.test.mock Android的一些輔助類
android.test.suitebuilder 工具 + 生產力類,支援類的測試回合
junit.framework中的方法解釋:
TestSuit:TestSuite是測試案例的集合;
TestCase:定義運行多個測試案例;
TestResult:收集一個測試案例的結果,測試結果分為失敗和錯誤,如果未能預計的斷言就是失敗,錯誤就像一個ArrayIndexOutOfBoundsException異常而導致的無法預料的問題;
TestFailure:測試失敗時捕獲的異常;
Assert:斷言的方法集,當宣告失敗時顯示資訊;
下面給出一個執行個體:
AndroidManifest.xml
[html]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.junit"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="com.android.junittest.MyJUnitActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Android JUnit配置 -->
<uses-library android:name="android.test.runner" />
</application>
<!-- 註:targetPackage與上面mainfest的package相同即可 -->
<instrumentation android:targetPackage="com.android.junit"
android:name="android.test.InstrumentationTestRunner"
android:label="Android JUnit測試" />
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.junit"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="com.android.junittest.MyJUnitActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Android JUnit配置 -->
<uses-library android:name="android.test.runner" />
</application>
<!-- 註:targetPackage與上面mainfest的package相同即可 -->
<instrumentation android:targetPackage="com.android.junit"
android:name="android.test.InstrumentationTestRunner"
android:label="Android JUnit測試" />
</manifest>
Activity類,只是給出一個介面,沒有實際的用途
[java]
package com.android.junit;
import com.android.junit.R;
import android.app.Activity;
import android.os.Bundle;
public class MyJUnitActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
package com.android.junit;
import com.android.junit.R;
import android.app.Activity;
import android.os.Bundle;
public class MyJUnitActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
需要測試的類
[java]
package com.android.junit;
public class Apps {
public void methodA() {
System.out.println("---Hello!");
}
public void methodB(String name) {
System.out.println("---Hello " + name + "!");
}
}
package com.android.junit;
public class Apps {
public void methodA() {
System.out.println("---Hello!");
}
public void methodB(String name) {
System.out.println("---Hello " + name + "!");
}
}
測試類別
[java]
<SPAN style="FONT-SIZE: 18px"><STRONG>package com.android.junittest;
import com.android.junit.Apps;
import android.test.AndroidTestCase;
public class AppsTester extends AndroidTestCase {
Apps a = null;
private int i1;
private int i2;
protected void setUp() throws Exception {
a = new Apps();
i1 = 1;
i2 = 2;
}
public void testMethodA() {
a.methodA();
}
public void testMethodB() {
a.methodB("Android");
}
//這是一個錯誤的測試
public void testAdd() {
assertTrue("testAddFailed", (i1 + i2) == 4);
}
public void testDec() {
assertTrue("testDecFailed", (i2 - i1) == 1);
}
}
</STRONG></SPAN>
package com.android.junittest;
import com.android.junit.Apps;
import android.test.AndroidTestCase;
public class AppsTester extends AndroidTestCase {
Apps a = null;
private int i1;
private int i2;
protected void setUp() throws Exception {
a = new Apps();
i1 = 1;
i2 = 2;
}
public void testMethodA() {
a.methodA();
}
public void testMethodB() {
a.methodB("Android");
}
//這是一個錯誤的測試
public void testAdd() {
assertTrue("testAddFailed", (i1 + i2) == 4);
}
public void testDec() {
assertTrue("testDecFailed", (i2 - i1) == 1);
}
}