1. 程式人生 > >Robotium自動化測試框架實用教程

Robotium自動化測試框架實用教程

一、簡介

Robotium是一款國外的Android自動化測試框架,主要針對Android平臺的應用進行黑盒自動化測試,它提供了模擬各種手勢操作(點選、長按、滑動等)、查詢和斷言機制的API,能夠對各種控制元件進行操作。Robotium結合Android官方提供的測試框架達到對應用程式進行自動化的測試。另外,Robotium 4.0版本已經支援對WebView的操作。Robotium 對Activity,Dialog,Toast,Menu 都是支援的。

二、相關下載

原始碼獲取:http://code.google.com/p/robotium/

源API文件:http://robotium.googlecode.com/svn/doc/index.html

 robotium5.1下載和最新API文件:http://pan.baidu.com/s/1bnlO8MF

官方例子記事本:http://pan.baidu.com/s/1qWLVL72

重簽名工具:http://pan.baidu.com/s/1i3H0tKD

三、常用語法

1.等待timeout毫秒一個名字為name的Activity啟動: waitForActivity(String name, int timeout) 
例項:assertTrue("無法啟動啟動類", solo.waitForActivity ("MainActivity", 30000));

2.Robotium將睡眠設定的毫秒數:sleep(int time) 
例項:solo.sleep(5000)

3.清空EditText的內容:clearEditText(android.widget.EditText editText) 
例項:solo.clearEditText((EditText)solo.getView ("edtInsertName"))

4.根據按鈕上的文字點選按鈕:clickOnButton(String text) 
例項:solo.clickOnButton("^綠色$");

5.根據文字點選控制元件:clickOnText(String text) 
例項:solo.clickOnText("控制元件上顯示文字");

6.輸入內容:enterText(android.widget.EditText editText, String text) 
solo.enterText((EditText)solo.getView("edtInsertName"), "說些什麼好呢?");

7.返回:goBack()

8.截圖並儲存為設定的名字:takeScreenshot(String name) 
預設儲存在: /sdcard/Robotium-Screenshots/


9.解鎖螢幕:unlockScreen()

四、實戰-針對APK進行的測試

 被測試專案為demo1,下面是實戰的具體步驟

1. 配置ANDROID_HOME為android sdk的安卓目錄,例如:D:\android-sdk

2. 在path下新增這兩個:%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;

3. 需要把APK重新簽名,因為robotium要求被測應用和測試程式碼要有一致的簽名, 所以我們需要把下載到的apk,通過re-sign.jar來產生debug key的apk,這個重新生成的apk就會跟測試專案簽名一致了

4. 下載完後,需要配置ANDROID_HOME
,就是安卓SDK的位置,然後把APK拉到圖示上,就會自動生成一個debug key的apk,如果無法直接單擊re-sign.jar執行,需要切換到放置該jar檔案的目錄,cmd執行java -jar re-sign.jar產生新apk的過程中會彈出一個資訊框,記得截下圖,因為裡面有兩個資訊我們等會的程式碼中需要用到

5. 安裝產生的apk。然後開啟模擬器(模擬器器一定要開啟才能安裝成功),然後開啟命令列  adb install mitalk_debug.apk(新生成apk的名稱) , 或者雙擊apk檔案也可以安裝

安裝成功就可以再模擬器裡看到該應用的圖示了

6. 開啟Eclipse,點選File->New一個Android Test Project  TestDemo1, 然後點選下一步的時候選擇This project(因為我們測試的是APK),然後選擇要在哪個android版本上測試

7. 在該專案下建立一個包,com.example.demo1.test,在該包下建立TestDemo1Apk類,如下

package com.example.demo1.test;

import com.robotium.solo.Solo;

import android.test.ActivityInstrumentationTestCase2;
import android.widget.EditText;

@SuppressWarnings("rawtypes")
public class TestDemo1Apk extends ActivityInstrumentationTestCase2 {

        private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.example.demo1.MainActivity";//啟動類

        private static Class<?> launcherActivityClass;
        static{
                try {
                        launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
                } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                }
        }
        
        @SuppressWarnings("unchecked")
        public TestDemo1Apk() throws ClassNotFoundException {
                super(launcherActivityClass);
        }
        
        private Solo solo;
        
        @Override
        protected void setUp() throws Exception {
                solo = new Solo(getInstrumentation(), getActivity());
        }


    	public void testcase001() throws Exception {
    		 //等待  Activity "MainActivity" 啟動
    		assertTrue("無法啟動啟動類", solo.waitForActivity("MainActivity", 30000));
            solo.sleep(5000);

          //輸入文字:"131243"
            solo.enterText((EditText)solo.getView("edtInsertName"), "說些什麼好呢?");
            solo.sleep(2000);
            
            //清空輸入框的內容
            solo.clearEditText((EditText)solo.getView("edtInsertName"));
            
            
            //按下 按鈕 "綠色"
            solo.clickOnButton("^綠色$");
            solo.sleep(2000);

            //按下 按鈕 "黃色"
            solo.clickOnButton("^黃色$");
            solo.sleep(2000);

            //按下 按鈕 "藍色"
            solo.clickOnButton("^藍色$");
            solo.sleep(2000);


            //按下 TextView "看我變變變~~~"
            solo.clickOnText("^看我變變變~~~$");
            solo.sleep(5000);      
            
    	}
    	

   @Override
   public void tearDown() throws Exception {
                solo.finishOpenedActivities();

  }


}

8.右鍵該專案,選擇property然後選擇java build path, 選擇 Add JARs,選擇下到的robotium.jar

Add Library,點選Junit,選擇Junit4

9.在跑測試用例之前,還需要修改下AndroidManifest.xml檔案的android:targetPackage為被測應用的根的包名

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.demo1" />

10.最後: run as android junit test,就可以進行測試了  

五、實戰-針對工作目錄下的專案

 被測試專案為demo1,下面是實戰的具體步驟

1.新建一個測試專案名為demo1Test

Eclipse-File-Project-Android Test Project

測試專案名為demo1Test,測試目標專案選擇demo1 

技術分享   

2.新增必要類庫,robotium和junit

(1)在專案中新建lib目錄,把robotium-solo-5.1.jar和robotium-solo-5.1-javadoc.jar拉進該目錄。

(2)新增junit4

技術分享

技術分享

技術分享

3.新增robotium

技術分享

技術分享

4.建立測試用例

右鍵點選包-New-JUnit Test Case

技術分享

最基礎的測試用例框架類

package com.example.demo1.test;

import com.example.demo1.MainActivity;//匯入目標專案的啟動類
import android.test.ActivityInstrumentationTestCase2;
import com.robotium.solo.Solo;


public class TestDemo1 extends ActivityInstrumentationTestCase2<MainActivity>{//繼承目標專案的啟動類

	private Solo solo;//初始化一個solo物件

	public TestDemo1() {//在建構函式處標明繼承自目標專案的啟動類
		super(MainActivity.class);
	}
	
	@Override
	public void setUp() throws Exception {//在測試開始之前會呼叫這個方法,這裡來建立一個Solo物件
		solo = new Solo(getInstrumentation(), getActivity());
	}

	@Override
	public void tearDown() throws Exception {//一個測試用例結束的時候會呼叫這個方法
		solo.finishOpenedActivities();//這個方法將結束掉所有在測試執行過程中開啟的activity
	}



}

在基礎測試類裡面新增相關的測試方法,也就是真正在執行的測試用例

package com.example.demo1.test;

import com.example.demo1.MainActivity;//匯入目標專案的啟動類
import android.test.ActivityInstrumentationTestCase2;
import android.widget.EditText;

import com.robotium.solo.Solo;


public class TestDemo1 extends ActivityInstrumentationTestCase2<MainActivity>{//繼承目標專案的啟動類

	private Solo solo;//初始化一個solo物件

	public TestDemo1() {//在建構函式處標明繼承自目標專案的啟動類
		super(MainActivity.class);
	}
	
	@Override
	public void setUp() throws Exception {//在測試開始之前會呼叫這個方法,這裡來建立一個Solo物件
		solo = new Solo(getInstrumentation(), getActivity());
	}

	
	public void testcase001() throws Exception {
		 //等待  Activity "MainActivity" 啟動
		assertTrue("無法啟動啟動類", solo.waitForActivity("MainActivity", 30000));
        solo.sleep(5000);

      //輸入文字:"131243"
        solo.enterText((EditText)solo.getView("edtInsertName"), "說些什麼好呢?");
        solo.sleep(2000);
        
        //清空輸入框的內容
        solo.clearEditText((EditText)solo.getView("edtInsertName"));
        
        
        //按下 按鈕 "綠色"
        solo.clickOnButton("^綠色$");
        solo.sleep(2000);

        //按下 按鈕 "黃色"
        solo.clickOnButton("^黃色$");
        solo.sleep(2000);

        //按下 按鈕 "藍色"
        solo.clickOnButton("^藍色$");
        solo.sleep(2000);


        //按下 TextView "看我變變變~~~"
        solo.clickOnText("^看我變變變~~~$");
        solo.sleep(5000);      
        
	}
	
	
	@Override
	public void tearDown() throws Exception {//一個測試用例結束的時候會呼叫這個方法
		solo.finishOpenedActivities();//這個方法將結束掉所有在測試執行過程中開啟的activity
	}



}

原始碼共享:http://pan.baidu.com/s/1mgKcgju

六、一些特殊設定的說明

1.新增到庫內需要先新建Lib目錄,再把robotium-solo-5.2.1.jar放到裡面,這樣移動專案就不會找不到

2.測試專案的AndroidManifest.xml裡面    <uses-sdk android:minSdkVersion="10" />需要在8以上,而且要跟被測試的專案一樣大

3.需要勾選

技術分享

4.最細節的就是:構造方法必須是無引數的,新建的測試用例一般都是有引數的:

public TestHelloWorldCase() {
super(HerlloActivity.class);
}

5.測試APK的時候需要重簽名,然後再安裝進去,才可以正常測試

6.如何配置Robotium的幫助提示

右鍵點選專案-Build Path-configure Build Path

技術分享

技術分享

7.robotium不同版本的方法不同

robotium的getCurrentListViews
1.版本3.6版本和4.1以上版本的表達方式

3.6版本:ArrayList<ListView> lw = solo.getCurrentListViews();

4.1版本以上:ArrayList<ListView> lw = solo.getCurrentViews(ListView.class);

還有如:

ArrayList<ImageView> imageList=solo.getCurrentViews(ImageView.class);得到的即是ImageView
ArrayList<ImageView> imageList=solo.getCurrentViews(ImageView.class,parentView);

8.如何獲取控制元件ID-兩種方法

(1)Android 實用工具Hierarchy Viewer實戰

  • 是隨AndroidSDK釋出的工具,位置在tools資料夾下,名為hierarchyviewer.bat
  • 需要執行測試專案,在除錯環境下才可以檢測到模擬器的

(2)執行命令列記錄log,然後點選對應Activity,接著可以在logcat看到