Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓006單元測試

安卓006單元測試

編輯:關於Android編程

Android 測試,日志

測試

常見測試分類
在介紹Android Junit前先介紹一下常見的測試分類。

 


根據是否知道源程序源碼:


 黑盒測試:不知源碼,只是測試程序的功能
 白盒測試:知道源碼,根據源代碼進行測試

 


根據測試的粒度:(模塊的大小)


 單元測試:unit test
 功能測試:function test:方法測試
 整合測試:integration test:幾個模塊的測試,服務器/客戶端的聯調
 系統測試:system test

 


根據測試的次數:(暴力測試)

 

 冒煙測試:smoke test,不停的執行操作,直到系統崩潰

Google提供了一個monkey
Adb shell:進入模擬器目錄,monkey
2000,通過monkey是隨機點擊2000次
monkey –p 包名 次數:只測試某個應用程序


 壓力測試:pressure test

 


Junit 測試框架


運行測試代碼:後台會幫我們做兩步操作


上傳當前應用程序到手機系統
發送指令通知手機測試剛才上傳的代碼


所以需要在清單文件裡配置:
 添加指令集(manifest節點下)
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.sqlitephone" />

targetPackage:是測試目標包


 指令集依賴jar包(application節點下)

 



Junit 測試步驟

 

 

 

單元測試

在實際開發中,開發android軟件的過程需要不斷地進行測試。而使用Junit 測試框架,則是正規的Android開發的必用技術,Android很好封裝了Junit測試框架,可以模擬發送事件和檢測程序處理的正確性

* Android單元測試實現流程

1.添加測試類庫

在AndroidManifest.xml 的 節點 添加測試類庫

2.設置測試環境

 

3. 編寫測試類

- 獲取上下文getContext()- 繼承AndroidTestCase

- 使用斷言 assertEquals()

- 查看測試效果

我們完成了一個業務方法,想要對其進行測試,Android程序是不能寫main
方法運行的,需要建測試項目。


1. 創建測試項目
創建測試工程
定義工程名
選擇要測試哪個工程

創建測試類,注意要繼承AndroidTestCase
編寫測試類
可以直接使用被測試工程中的業務類,測試方法必須以小寫“test”開頭

2. 不創建測試項目,加測試類
在AndroidManifest.xml清單文件中添加配置
< instrumentation android:targetPackage= "cn.itcast.junit"
android:name= "android.test.InstrumentationTestRunner" />

定義一個類繼承AndroidTestCase,定義測試方法


Junit 單元測試


 新建業務方法
例如計算器的加法:
// 計算器
public class Calc {
/**
* 計算器相加的方法
* @param x
* @param y
* @return
*/
public int add(int x, int y) {
return x + y;
}
}
 新建Junit測試類,對add方法進行單元測試

//Android中想要進行單元測試 需要繼承AndroidTestCase
public class TestCalc extends AndroidTestCase{
//需要寫一個測試方法
public void testAdd(){
//想測試 計算器相加的方法
Calc calc = new Calc();
int result = calc.add(5, 6);
//斷言
assertEquals(11,result);
}
}
 在清單文件中添加測試指令

android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.itheima.unit"
android:label="Tests for My App" />
 運行測試方法testAdd
如圖:雙擊方法,右鍵Run As——Android Junit Test
運行結果:綠條代表測試通過。


Junit 單元測試,在公司中會用到,所以大家需要掌握。

Android Junit 拓展知識
注意:拓展知識並不是必須要求掌握的,心有余力之時可以作為進一步提升的
參考。
Android
測試環境的核心是一個Instrumentation框架,在這個框架下,你的測試應用程序
可以精確控制應用程序。使用Instrumentation,
你可以在主程序啟動之前,創建模擬的系統對象,如Context;控制應用程序的
多個生命周期;發送UI事件給應用程序;在執行期間檢查程序狀態。
Instrumentation框架通過將主程序和測試程序運行在同一個進程來實現這些功能

通過在測試工程的manifest文件中添
元素來指定要測試的應用程序。這個元素的特性指明了要測
試的應用程序包名,以及告訴Android如何運行測試程序。下面的圖片概要的描
述了Android的測試環境:

Android中,測試程序也是Android程序,因此,它和被測試程序的書寫方式有
很多相同的地方。SDK工具能幫助你同時創建主程序工程及它的測試工程。你
可以通過Eclipse的ADT插件或者命令行來運行Android測試。Eclipse的ADT提供
了大量的工具來創建測試用例,運行以及查看結果。
Android提供了基於JUnit測試框架的測試API來書寫測試用例和測試程序。
另外,Android還提供了強大的Instrumentation框架,允許測試用例訪問程序的
狀態及運行時對象。


Android Junit 中的主要核心API
 JUnit TestCase類
繼承自JUnit的TestCase,不能使用Instrumentation框架。但這些類包含
訪問系統對象(如Context)的方法。使用
Context,你可以浏覽資源,文件,數據庫等等。基類是AndroidTestCase,一
般常見的是它的子類,和特定組件關聯。
子類有:
 ApplicationTestCase——
測試整個應用程序的類。它允許你注入一個模擬的Context到應用程
序中,在應用程序啟動之前初始化測試參數,並在應用程序結束之
後銷毀之前檢查應用程序。
 ProviderTestCase2——
測試單個ContentProvider的類。因為它要求使用MockContentResolve
r,並注入一個IsolatedContext,因此Provider的測試是與OS孤立的

 ServiceTestCase——
測試單個Service的類。你可以注入一個模擬的Context或模擬的Appl
ication(或者兩者),或者讓Android為你提供Context和MockApplic
ation。
 Instrumentation TestCase類
繼承自JUnit
TestCase類,並可以使用Instrumentation框架,用於測試Activity。使用Instrument
ation,Android可
以向程序發送事件來自動進行UI測試,並可以精確控制Activity的啟動,監測Ac
tivity生命周期的狀態。
基類是InstrumentationTestCase。它的所有子類都能發送按鍵或觸摸事件
給UI。子類還可以注入一個模擬的Intent。子類有:
 ActivityTestCase——Activity測試類的基類。
 SingleLaunchActivityTestCase——
測試單個Activity的類。它能觸發一次setup()和tearDown(),而不是
每個方法調用時都觸發。如果你的測試方法都是針對同一個Activity
的話,那就使用它吧。
黑馬Android課程筆記 就業服務部出品
 SyncBaseInstrumentation——測試Content
Provider同步性的類。它使用Instrumentation在啟動測試同步性之前
取消已經存在的同步對象。
 ActivityUnitTestCase——
對單個Activity進行單一測試的類。使用它,你可以注入模擬的Cont
ext或Application,或者兩者。它用於對Activity進行單元測試。不同
於其它的Instrumentation類,這個測試類不能注入模擬的Intent。
 ActivityInstrumentationTestCase2——
在正常的系統環境中測試單個Activity的類。你不能注入一個模擬的
Context,但你可以注入一個模擬的Intent。另外,你還可以在UI線
程(應用程序的主線程)運行測試方法,並且可以給應用程序UI發
送按鍵及觸 摸事件。
 Assert類
Android還繼承了JUnit的Assert類,其中,有兩個子類,MoreAsserts和Vi
ewAsserts。
 MoreAsserts類包含更多強大的斷言方法,如assertContainsRegex(Stri
ng, String),可以作正則表達式的匹配。
 ViewAsserts類包含關於Android
View的有用斷言方法,如assertHasScreenCoordinates(View, View,
int,
int),可以測試View在可視區域的特定X、Y位置。這些Assert簡化
了UI中幾何圖形和對齊方式的測試。
 Mock對象類
Android
有一些類可以方便的創建模擬的系統對象,如Application,Context,Content
Resolver和Resource。Android還在一些測試類中提供了一些方法來創建模擬的In
tent。因為這些模擬的對象比實際對象更容易使
用,因此,使用它們能簡化依賴注入。你可以在android.test和android.test.mock
中找到這些類。
它們是:
 IsolatedContext——
模擬一個Context,這樣應用程序可以孤立運行。與此同時,還有大
量的代碼幫助我們完成與Context的通信。這個類在單元測試時很有
用。
黑馬Android課程筆記 就業服務部出品
 RenamingDelegatingContext——
當修改默認的文件和數據庫名時,可以委托大多數的函數到一個存
在的、常規的Context上。使用這個類來測試文件和數據庫與正常的
系統Context之間的操作。
 MockApplication,MockContentResolver,MockContext,MockDialogInter
face,MockPackageManager,MockResources ——
創建模擬的系統對象的類。它們只暴露那些對對象的管理有用的方
法。這些方法的默認實現只是拋出異常。你需要繼承這些類並重寫
這些方法。
 Instrumentation TestRunner
Android
提供了自定義的運行測試用例的類,叫做InstrumentationTestRunner。這個類控
制應用程序處於測試環境中,在同一個進程中運行測試
程序和主程序,並且將測試結果輸出到合適的地方。IntrumentationTestRunner
在運行時對整個測試環境的控制能力的關鍵是使用
Instrumentation。注意,如果你的測試類不使用Instrumentation的話,你也可以
使用這個TestRunner。
當你運行一個測試程序時,首先會運行一個系統工具叫做Activity
Manager。Activity
Manager使用Instrumentation框架來啟動和控制TestRunner,這個TestRunner反過
來又使用
Intrumentation來關閉任何主程序的實例,然後啟動測試程序及主程序(同一個
進程中)。這就能確保測試程序與主程序間的直接交互。
在測試環境中工作
對Android程序的測試都包含在一個測試程序裡,它本身也是一個Android
應用程序。測試程序以單獨的Android工程存在,與正常的Android程序有著相
同的文件和文件夾。測試工程通過在manifest文件中指定要測試的應用程序。
每個測試程序包含一個或多個針對特定類型組件的測試用例。測試用例裡
定義了測試應用程序某些部分的測試方法。當你運行測試程序,Android會在相
同進程裡加載主程序,然後觸發每個測試用例裡的測試方法。
測試工程
為了開始對一個Android程序測試,你需要使用Android工具創建一個測試
工程。工具會創建工程文件夾、文件和所需的子文件夾。工具還會創建一個ma
nifest文件,指定被測試的應用程序。
黑馬Android課程筆記 就業服務部出品
測試用例
一個測試程序包含一個或多個測試用例,它們都繼承自Android
TestCase類。選擇一個測試用例類取決於你要測試的Android組件的類型以及你
要做什麼樣的測試。一個測試程序可以測試不同的組件,但每個測試用例類設
計時只能測試單一類型的組件。
一些Android組件有多個關聯的測試用例類。在這種情況下,在可選擇的
類間,你需要判斷你要進行的測試類型。例如,對於Activity來說,你有兩個選
擇,ActivityInstrumentationTestCase2和ActivityUnitTestCase。
ActivityInstrumentationTestCase2設計用於進行一些功能性的測試,因此
,它在一個正常的系統環境中測試Activity。你可以注入模擬的Intent,但不能
是模擬的Context。一般來說,你不能模擬Activity間的依賴關系。相比而言,A
ctivityUnitTestCase設計用於單元測試,因此,它在一個孤立的系統環境中測試
Activity。換句話說,當你使用這個測試類時,Activity不能與其它Activity交互

作為一個經驗法則,如果你想測試Activity與Android的交互的話,使用Acti
vityInstrumentationTestCase2。如果你想對一個Activity做回歸測試的話,使用Ac
tivityUnitTestCase。
測試方法
每個測試用例類提供了可以建立測試環境和控制應用程序的方法。例如,
所有的測試用例類都提供了JUnit的setUp()方法來搭建測試環境。另外,你可以
添加方法來定義單獨的測試。當你運行測試程序時,每個添加的方法都會運行
一次。如果你重寫了setUp()方法,它會在每個方法運行前運行。相似
的,tearDown()方法會在每個方法之後運行。
測試用例類提供了大量的對組件啟動和停止控制的方法。由於這個原因,
在運行測試之
前,你需要明確告訴Android啟動一個組件。例如,你可以使用getActivity()來啟
動一個Activity。在整個測試用例期間,你只能調
用這個方法一次,或者每個測試方法一次。甚至你可以在單個測試方法中,調
用它的finishing()來銷毀Activity,然後再調用 getActivity()重新啟動一個。
運行測試並查看結果
編譯完測試工程後,你就可以使用系統工具Activity
Manager來運行測試程序。你給Activity
Manager提供了TestRunner的名(一般是InstrumentationTestRunner,在程序中指
定);名包括被測試程序的包名和 TestRunner的名。Activity
Manager加載並啟動你的測試程序,殺死主程序的任何實例,然後在測試程序的
同一個進程裡加載主程序,然後傳遞測試程序的第一個測試用例。這個時
候,TestRunner會接管這些測試用例,運行裡面的每個測試方法,直到所有的
方法運行結束。
黑馬Android課程筆記 就業服務部出品
如果你使用Eclipse,結果會在JUnit的面板中顯示。如果你使用命令行,
將輸出到STDOUT上。
測試什麼?
除了一些功能測試外,這裡還有一些你應該考慮測試的內容:
Activity生命周期事件:你應該測試Activity處理生命周期事件的正確性。例如,
一個Activity應該在pause或destroy事件
時保存它的狀態。記住一點的是屏幕方向的改變也會引發當前Activity銷毀,因
此,你需要測試這種偶然情況確保不會丟失應用程序狀態。
數據庫操作:你應該確保數據庫操作能正確處理應用程序狀態的變化。使用and
roid.test.mock中的模擬對象。
屏幕大小和分辨率:在發布程序之前,確保在所有要運行的屏幕大小和分辨率
上測試通過。你可以使用AVD來測試,或者使用真實的目標設備進行測試。
UI 線程中測試
Activity運行在程序的UI線程裡。一旦UI初始化後,例如在Activity的onCrea
te()方法後,所有與UI的交互都必須運行在UI線程裡。當你正常運行程序時,它
有權限可以訪問這個線程,並且不會出現什麼特別的事情。當你運行測試程序
時,這一點發生了變化。在帶有instrumentation的類裡,你可以觸發方法在UI線
程裡運行。其它的測試用例類不允許這麼做。
為了一個完整的測試方法都在UI線程裡運行,你可以使用@UIThreadTest來
聲明線程。注意,這將會在UI線程裡運行方法裡所有的語句。不與UI交
互的方法不允許這麼做;例如,你不能觸發Instrumentation.waitForIdleSync()。
如果讓方法中的一部分代碼運行在UI線程的話,創建一個匿名的Runnabl
e對象,把代碼放到run()方法中,然後把這個對象傳遞給appActivity.runOnUiThr
ead(),在這裡,appActivity就是你要測試的app對象。

 


日志信息
LogCat 介紹
Android
LogCat的獲取有兩種方式:1、DDMS提供的LogCat視圖2、通過adb命令行
 DDMS提供的LogCat視圖如下

如果該視圖沒有打開,點擊window->show view->other->android-
>Logcat來進行選擇。
視圖的左側可以選擇或者添加過濾信息,運行一個應用程序時,此處會默
認創建一個該包的過濾。視圖的右上角區域用於選擇LogCat的log級別,共有ver
bose、debug、info、warn、error、assert6個可選項。如圖所示:

該視圖的主體部分是log的詳細信息,包括錯誤級別(Level)、時間(Tim
e)、進程ID(PID)、線程ID(TID)、應用程序包名(Application)、標簽(
Tag)、日志正文(Text)。
其中的TID並不等同於Java中的Thread.currentThread().getId(),而是我們Linux
中的Thread ID,跟PID相同。
 通過命令行調用LogCat
 將LogCat信息顯示在控制台中
在控制台中輸入adb logcat
然後按回車鍵即可看到LogCat信息,如果需要終止按Ctrl+C鍵即可。
 將LogCat信息保存在文件中

執行adb logcat >D:/a.txt
則將日志輸出到D:/a.txt文件中。按Ctrl+C鍵終止日志的輸出。
上面介紹的只是adb
logcat命令的最簡單用法,其實該命令還有多種可選參數供選擇,這裡就不再詳
細說明。


Logcat 的日志等級
android.util.Log常用的方法有以下5個:
Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根據首字母對應VERBOSE
,DEBUG,INFO, WARN ,ERROR。
 Log.v
的調試顏色為 黑色的,任何消息都會輸出,這裡的v代表verbose啰嗦的意思
,平時使用就是Log.v("","");
 Log.d的輸出顏色是 藍色的,僅輸出debug調試的意思,但他會輸出上層的信
息,過濾起來可以通過DDMS的Logcat標簽來選擇.
 Log.i的輸出為 綠色,一般提示性的消息information,它不會輸出Log.v和Log
.d的信息,但會顯示i、w和e的信息,System.out輸出信息是Info級別
 Log.w的意思為 橙色,可以看作為warning警告,一般需要我們注意優化And
roid代碼,同時選擇它後還會輸出Log.e的信息。
 Log.e為紅色,可以想到error錯誤,這裡僅顯示紅色的錯誤信息,這些錯誤
就需要我們認真的分析,查看棧的信息了。
 程序中我們可以使用Log類來輸出信息

結果:
Logcat 通過tag 過濾
tag:可以利用tag進行過濾,用於查找日志。
在logcat中可以添加一個日志過濾器,選擇日志等級,會顯示出當前等級和比當
前等級高的等級。選擇warn,會出現warn和error兩種日志。還可以使用System.
out來打印日志(info級別),System.error(警告級別)
Logcat 日志激活
激活日志,ddms中隨便點擊devices中的一項即可。其實日志是打印在模擬器裡
的,系統通過adb,將日志信息傳遞到開發平台的logcat中
如果還是沒有打印日志,就重啟adb或eclipse,然後也可以通過命令adb
logcat,可在cmd中查看日志

案例-Android 程序獲取LogCat 信息
下面通過創建一個Android工程來演示如何在代碼中實時獲取LogCat信息。

 

 


 創建一個新工程,這裡工程名為LogCat
在這個工程中使用默認的MainActivity.java類和默認的布局文件。
 修改布局文件
xmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:tools= "http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:orientation= "vertical"
tools:context= ".MainActivity" >
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text= "獲取LogCat"
android:id= "@+id/bt_click"
/>
android:id= "@+id/tv_show"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:hint= "顯示日志"
/>


 修改MainActivity.java代碼
代碼第一部分:
package com.itheima.com.logcat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
protected static final String TAG = "MyTest";
private Button btn;
private TextView tv_show;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
tv_show.setText((String) msg.obj);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.bt_click);
tv_show = (TextView) findViewById(R.id.tv_show);
黑馬Android課程筆記 就業服務部出品
代碼第二部分:
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.v(TAG, "這是verbose信息");
Log.d(TAG, "這是debug信息");
Log.i(TAG, "這是info信息");
Log.w(TAG, "這是warn信息");
Log.e(TAG, "這是error信息");
/** 開啟線程用於監聽log輸出的信息 **/
new Thread(new Runnable() {
@Override
public void run() {
Process mLogcatProc = null;
BufferedReader reader = null;
try {
/*
*
通過執行命令行獲取LogCat信息
*/
mLogcatProc =
Runtime.getRuntime().exec(new String[] { "logcat", TAG + ":v *:s"
});
/*
* 獲取進程輸出流對象
*/
reader = new
BufferedReader(new
InputStreamReader(mLogcatProc.getInputStream()));
String line = null;
StringBuilder sb = new
StringBuilder();

代碼第三部分(完):
while ((line = reader.readLine()) != null) {
sb.append(line);
Message msg =
Message.obtain();
msg.obj =
sb.toString();
handler.sendMessage(msg);
}
reader.close();
/*
*
通過發送消息,通知主線程修改TextView對象
*
因此這個操作是在子線程中進行的,而Android應用中子線程是無法修改UI(UI的修改
操作必須在
* 主線程中進行
*
,因此Android提供了Handler機制,讓子線程發送消息給主線程,然後由主線程修改U

I).
*/
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
});
}
}


 將項目運行在模擬器上,並點擊按鈕
運行結果如圖所示:
結合工作和面試
 面試中
 Junit測試
面試中有可能會被問到,你們公司以前是怎麼去測試的?
你可以說我們公司比較規范,有的功能會用Junit測試。也可以說,
我們就是手工測試,自己測試沒問題了,提交給測試人員去測試。
然後他們提交bug,我們修復。
 日志信息
面試中,會被問到,你是怎麼解決bug的?
一般說下,斷點調試,變量分析,日志跟蹤即可。
變量分析就是斷點調試過程中,對變量的值進行監控,看是否為null
,或者不正常。
 工作中
 Junit測試

這個會使用即可,一般的小公司不會讓做Junit測試,就是手測。大
公司,制度比較嚴格的可能會要求做Junit測試。要做也是一般的單
元測試,所以大家單元測試需要掌握。
主要還是測試人員寫測試用例去測。
 日志信息
上邊也提到過了,這個比較重要,一定要會看日志信息,對代碼分
析,bug調試很有幫助。
還有就是有些同學的日志有時候出現不了,參照Logcat日志激活,
一般就是設備沒連接成功,連接後有可能需要選擇一下連接的設備。

 

 

 

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved