Android系列----JUnit單元測試的使用


【聲明】 

歡迎轉載,但請保留文章原始出處→_→ 

生命壹號: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()方法的單元測試,后台輸出如下:

 

三、常見測試方法:

黑盒測試: 是以用戶的角度,從輸入數據與輸出數據的對應關系出發進行測試的。

白盒測試: 又稱結構測試、透明盒測試、邏輯驅動測試或基於代碼的測試。

單元測試: 又稱模塊測試,是開發者編寫的一小段代碼,用於檢驗被測代碼的一個很小的、很明確的功能是否正確。

功能測試: 根據產品特性、操作描述和用戶方案,測試一個產品的特性和可操作行為以確定它們滿足設計需求。

壓力測試: 主體向被觀察者布置一定量任務和作業,借以觀察個體完成任務的行為。

集成測試: 是單元測試的邏輯擴展。它的最簡單的形式是:兩個已經測試過的單元組合成一個組件,並且測試它們之間的接口

備注:黑盒測試,不看代碼結構,從用戶的角度測試功能,例如玩某一款游戲來測試。白盒測試:通過代碼測試功能。

 

軟件測試可以從不同的角度加以分類:
基於是否關注軟件結構與算法:

  • 黑盒測試
  • 白盒測試

基於是否執行被測試軟件:

  • 靜態測試
  • 動態測試

基於測試的不同階段:

  • 單元測試
  • 集成測試
  • 系統測試
  • 驗收測試

此外還有壓力測試等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM