【聲明】
歡迎轉載,但請保留文章原始出處→_→
生命壹號:http://www.cnblogs.com/smyhvae/
文章來源:http://www.cnblogs.com/smyhvae/p/4020443.html
【正文】
一、單元測試的引入:
如果只是普通的一個小程序,編寫測試是有些多此一舉,但是當項目比較龐大的時候,一般都應該去編寫單元測試。JUnit測試是白盒測試,即主要是程序員自己對開發的方法進行功能性測試。JUnit是一套框架,Android中也沿用了這一套框架。
在Android中使用JUnit測試大致分如下幾個步驟:
- (1)在AndroidManifest.xml中增加對JUnit的支持,並制定測試項目包。
- (2)在AndroidManifest.xml中<application.../>節點中增加一個<uses-library...>節點,name屬性為android.test.runner。
- (3)在編寫待測試方法后,新建一個類,繼承AndroidTestCase,在其中編寫測試用例代碼。
- (4)鼠標左鍵在測試用例方法上,Run As→Android JUnit Test。
二、步驟詳解:
(1)配置清單文件:
新建Android工程文件,命名為m05_SharedPreferencesTest,
首先在AndroidManifest.xml添加一個Instrumentation:
指定Instrumentation的name與TargetPackage:
然后保存。
緊接着在<application.../>節點中增加<uses-library android:name="android.test.runner" />。
完成后,AndroidManifest.xml代碼如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.m05_sharedpreferencestest" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="16" /> 10 11 <instrumentation 12 android:name="android.test.InstrumentationTestRunner" 13 android:targetPackage="com.example.m05_sharedpreferencestest" > 14 </instrumentation> 15 16 <application 17 android:allowBackup="true" 18 android:icon="@drawable/ic_launcher" 19 android:label="@string/app_name" 20 android:theme="@style/AppTheme" > 21 <uses-library android:name="android.test.runner" /> 22 23 <activity android:name="com.example.m05_sharedpreferencestest.MainActivity" 24 android:label="@string/app_name" > 25 <intent-filter> 26 <action android:name="android.intent.action.MAIN" /> 27 28 <category android:name="android.intent.category.LAUNCHER" /> 29 </intent-filter> 30 </activity> 31 </application> 32 33 </manifest>
上方11至14行以及21行是我們所添加的代碼。請將第13行改為自己的包名。
編寫一個類,我們需要做的是在里面實現記住密碼的功能:
通過SharedPreferences保存用戶輸入的用戶名、密碼:
package com.example.m05_sharedpreferencestest; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; public class LoginService { private Context context; //為了獲取SharedPreferences這個類,我們需要一個上下文對象 public LoginService(Context context) { // TODO Auto-generated constructor stub this.context = context; } //方法:通過SharedPreferences保存用戶輸入的用戶名、密碼 public boolean saveLoginMsg(String name,String pwd) { boolean flag = false; SharedPreferences sp = context.getSharedPreferences("login", 0); Editor editor = sp.edit(); editor.putString("username", name); editor.putString("password", pwd); flag = editor.commit(); return flag; } }
編寫一個測試類,這個類需要繼承AndroidTestCase,針對上面的方法進行測試:
package com.example.m05_sharedpreferencestest; import android.test.AndroidTestCase; import android.util.Log; public class Mytest extends AndroidTestCase { public Mytest() { // TODO Auto-generated constructor stub } public void save(){ LoginService loginService = new LoginService(getContext()); boolean flag = loginService.saveLoginMsg("smyhvae", "smyh"); //如果數據保存成功,saveLoginMsg()方法將返回true值。 Log.i("Mytest", ""+flag); } }
現在來運行單元測試中的這個方法。右鍵選中save()方法,選中run as -->Android JUnit Test:
當執行成功后,會顯示綠色,如果是其他顏色,則出錯:
我們同樣也能在login.xml文件中查看到內容:
我們剛剛保存的只是字符串類型。如果想要保存任何數據類型,可以在LoginService.java中添加如下方法:
public boolean saveSharePreference(String fileName, Map<String, Object> map) { boolean flag = false; SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); Editor editor = preferences.edit(); for (Map.Entry<String, Object> entry : map.entrySet()) { String key = entry.getKey(); Object object = entry.getValue(); if (object instanceof Boolean) { Boolean new_name = (Boolean) object; editor.putBoolean(key, new_name); } else if (object instanceof Integer) { Integer integer = (Integer) object; editor.putInt(key, integer); } else if (object instanceof Float) { Float f = (Float) object; editor.putFloat(key, f); } else if (object instanceof Long) { Long l = (Long) object; editor.putLong(key, l); } else if (object instanceof String) { String s = (String) object; editor.putString(key, s); } } flag = editor.commit(); return flag; }
運行單元測試后,msg.xml中的內容如下:
我們既然將數據存進去了,然后想將它讀出來。需要再增加一個方法。代碼實現見下面的內容。
【代碼匯總】
總的來說,完整版代碼如下:
LoginService.java代碼如下:
1 package com.example.m05_sharedpreferencestest; 2 3 import java.util.Map; 4 import android.content.Context; 5 import android.content.SharedPreferences; 6 import android.content.SharedPreferences.Editor; 7 8 public class LoginService { 9 10 private Context context; //為了獲取SharedPreferences這個類,我們需要一個上下文對象 11 public LoginService(Context context) { 12 // TODO Auto-generated constructor stub 13 this.context = context; 14 } 15 16 //方法:通過SharedPreferences保存用戶輸入的用戶名、密碼(字符串類型) 17 public boolean saveLoginMsg(String name,String pwd) { 18 boolean flag = false; 19 SharedPreferences sp = context.getSharedPreferences("login", 0); 20 Editor editor = sp.edit(); 21 editor.putString("username", name); 22 editor.putString("password", pwd); 23 flag = editor.commit(); 24 return flag; 25 } 26 27 //方法:通過SharedPreferences保存用戶輸入的用戶名、密碼(各種數據類型) 28 public boolean saveSharePreference(String fileName, Map<String, Object> map) { 29 boolean flag = false; 30 SharedPreferences preferences = context.getSharedPreferences(fileName, 31 Context.MODE_PRIVATE); 32 Editor editor = preferences.edit(); 33 for (Map.Entry<String, Object> entry : map.entrySet()) { 34 String key = entry.getKey(); 35 Object object = entry.getValue(); 36 if (object instanceof Boolean) { 37 Boolean new_name = (Boolean) object; 38 editor.putBoolean(key, new_name); 39 } else if (object instanceof Integer) { 40 Integer integer = (Integer) object; 41 editor.putInt(key, integer); 42 } else if (object instanceof Float) { 43 Float f = (Float) object; 44 editor.putFloat(key, f); 45 } else if (object instanceof Long) { 46 Long l = (Long) object; 47 editor.putLong(key, l); 48 } else if (object instanceof String) { 49 String s = (String) object; 50 editor.putString(key, s); 51 } 52 } 53 flag = editor.commit(); 54 return flag; 55 } 56 57 //方法:數據存儲之后,然后讀出來 58 public Map<String, ?> getSharePreference(String fileName) { 59 Map<String, ?> map = null; 60 SharedPreferences preferences = context.getSharedPreferences(fileName, 61 Context.MODE_PRIVATE); 62 map = preferences.getAll(); 63 return map; 64 } 65 66 }
MyTest.java代碼如下:
1 package com.example.m05_sharedpreferencestest; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import android.test.AndroidTestCase; 7 import android.util.Log; 8 9 public class Mytest extends AndroidTestCase { 10 11 private final String TAG = "Mytest"; 12 public Mytest() { 13 // TODO Auto-generated constructor stub 14 } 15 16 public void save(){ 17 LoginService loginService = new LoginService(getContext()); 18 boolean flag = loginService.saveLoginMsg("smyhvae", "smyh"); 19 //如果數據保存成功,saveLoginMsg()方法將返回true值。 20 Log.d(TAG, ""+flag); 21 } 22 23 24 public void save2() { 25 LoginService service = new LoginService(getContext()); 26 Map<String, Object> map = new HashMap<String, Object>(); 27 map.put("name", "jack"); 28 map.put("age", 23); 29 map.put("salary", 3000.0f); 30 map.put("id", 1010010101l); 31 map.put("isManager", true); 32 boolean flag = service.saveSharePreference("msg", map); 33 Log.i(TAG, "--->>" + flag); 34 } 35 36 37 public void read() { 38 LoginService service = new LoginService(getContext()); 39 Map<String, ?> map = service.getSharePreference("msg"); 40 Log.i(TAG, "--->" + map.get("name")); 41 Log.i(TAG, "--->" + map.get("age")); 42 Log.i(TAG, "--->" + map.get("salary")); 43 Log.i(TAG, "--->" + map.get("id")); 44 Log.i(TAG, "--->" + map.get("isManager")); 45 } 46 }
如果執行read()方法的單元測試,后台輸出如下:
三、常見測試方法:
黑盒測試: 是以用戶的角度,從輸入數據與輸出數據的對應關系出發進行測試的。
白盒測試: 又稱結構測試、透明盒測試、邏輯驅動測試或基於代碼的測試。
單元測試: 又稱模塊測試,是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。
功能測試: 根據產品特性、操作描述和用戶方案,測試一個產品的特性和可操作行為以確定它們滿足設計需求。
壓力測試: 主體向被觀察者布置一定量任務和作業,借以觀察個體完成任務的行為。
集成測試: 是單元測試的邏輯擴展。它的最簡單的形式是:兩個已經測試過的單元組合成一個組件,並且測試它們之間的接口
備注:黑盒測試,不看代碼結構,從用戶的角度測試功能,例如玩某一款游戲來測試。白盒測試:通過代碼測試功能。
軟件測試可以從不同的角度加以分類:
基於是否關注軟件結構與算法:
- 黑盒測試
- 白盒測試
基於是否執行被測試軟件:
- 靜態測試
- 動態測試
基於測試的不同階段:
- 單元測試
- 集成測試
- 系統測試
- 驗收測試
此外還有壓力測試等。