這里需要把Instrumentation類的視頻的上、中、下三集一起看,把內容總結一下。。。
視頻地址:
http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=881433&courseId=712011
http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=878104&courseId=712011
http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877119&courseId=712011
一、引子(面試題)
如何在一個app中做event事件?(touch、滑動和按鍵等)
答:
1、Device.touch(x,y) //monkeyrunner的方法
2、solo.clickOnView(String id) //Robotium的方法
3、driver.findElement(By.name("xxx")).click() //Selenium的方法
4、不采用任何開源或非開源的測試框架(monkeyrunner、robotium、appium、selenium、Androiddriver、uiautomator等都不許用)
此時就需要用google提供的基礎測試類Instrumentation
注:Robotium就是基於Instrumentation的二次封裝,所以理解Robotium的原理還在於Instrumentation
問題:
1、Robotium的運行原理是什么?
答:Robotium是通過對instrumentation的注入事件(sendKeyDownUpSync、sendPointerSync)的封裝、以及通過調用instrumentation的runOnMainSync、runOnUiThread等來完成對控件的操作,讓用戶可以直接調用一個solo.clickOnText等方法,就能夠完成操作,而不用自己去寫一堆找到控件,然后再點擊觸發等方法
2、為什么Robotium的testcase需要一個setup方法和一個teardown方法
答:分析Instrumentation的原理,InstrumentationTestCase或者InstrumentationTestCase2都需要有一個setUp和tearDown方法,一個用來進行前期准備,獲取所有需要的東西,比如說主Activity,比如說獲取到所有的控件ID,然后在下面的test方法中才能用這些ID進行相應測試的操作。
根本原因是因為:setup和teardown是junit必須執行的生命周期函數,所有的Test類都是基於這個做的,所以必須要有這兩個方法才行。
3、Robotium的AndroidManifest.xml中配置的節點<Instrumentation>又是什么含義?不導入jnuit-report.jar包的時候,Instrumentation中配置的 android:name="android.test.InstrumentationTestRunner",如果用了這個jnuit-report.jar包之后,就需要修改Instrumenation的節點配置為android:name="com.zutubi.android.junitreport.JUnitReportTestRunner"?
答:按照理解,這個配置的Instrumentation節點的anroid:name指的就是用以啟動的TestRuner的名,只有配置了這個之后,測試程序才能夠啟動起來,這個啟動過程應該又回到上一篇Robotium里面記錄的那樣了,運行一個測試程序,會先運行一個系統工具Activity Manager,然后Activity Manager通過Instrumentation框架來啟動和控制TestRunner,但是你需要給Activity Manager提供TestRuner的名,就是指的這里配置的android:name
Instrumentation的這個AndroidManifest.xml的標簽中的配置(該標簽位於Application標簽的外面):
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="xxx.xxx.xxx"/>
android:name指定TestRunner,這就是導入了一個命名空間,一個包名,就是android.test.Instrumentation,這個標簽一導入,系統就知道你要應用Instrumentation測試框架了
二、萬能的Instrumentation類
First:what is Instrumentation?
答:
Instrumentation是執行Application Instrumentation代碼的基類,當應用程序運行的時候Instrumentation處於開啟(備注:需要了解應用程序運行之前就已經開啟哪些東西?),Instrumentation將在任何應用程序運行前初始化,可以通過它監測系統與應用程序之間的交互。
Second:how to implement the Instrumentation?
答:
Instrumentation的實現是通過在AndroidManifext.xml中加一個<Instrumentation>的標簽,具體如下:
Third:how to understand the Instrumentation?
答:
Instrumentaion比較像Windows里面的鈎子(Hook),在系統和應用程序之間裝了一個特殊裝置用以進行監聽
做自動化測試的時候用到的類是:InstrumetationTestCase類,(Instrumentation是一個測試基類,InstrumentationTestCase是一個測試框架,那么具體Android本身官方提供的多個測試類之間是個啥樣的關系呢??
Robotium是對InsttumentationTestCase2的二次封裝,這個InstrumentationTestCase其實跟InstrumenatationTestCase2已經有點差別了,InstrumentationTestCase2已經對InstrumentationTestCase做了一個簡化處理,比如增加了public方法getActivity(),就可以直接獲得當前被測對象的Activity,而不用像在InstrumentationTestCase里面那樣,通過getInstrumentation().startActivitySync(intent)方法來獲取Activity了。。。
三、實現touch、keyEvent等事件
1、准備安卓的環境(java環境、eclipse、環境變量配置)
2、寫一個安卓的app(被測app)
3、開始寫測試框架代碼
測試必須要保證測試app和被測程序簽名一致,既然是自己寫的,那么肯定是用debug簽名比較方便,這樣被測代碼和測試代碼在不同的包中,但是在同一個工程里,簽名肯定一致;如果沒有源碼的話,也需要簽名一致,就需要進行重簽名了。
具體的代碼就是,建一個包名來創建app,然后一個待測程序建立一個包,一個測試程序建立一個包。
Instrumentation對安卓操作系統的版本沒有要求,這個是特別好的
demo1:實現對一個button的點擊操作
具體代碼內容詳解:
1、Intent.setClassName(packageName, MainActivity.class.getName)方法
2、startActivitySync(Intent intent)方法:
Intent是一個意圖,在安卓開發里面可以通過Intent.setClass,之后用this.startActivity(Intent intent)就可以跳轉到你想要去的那個Activity
startActivitySync的這個方法,在啟動了這個APP之后,將這個Intent傳遞給他,然后它就能夠給你返回當前的MainActivity
3、Junit4的assertEquals和robotium的searchText
assertEquals方法需要輸入expected string和actual string,然后兩者進行比較,返回是否相等,用此來做校驗;
serchText方法是將所有的TextView全部找到,放到一個集合中,然后去做對比(通過正則表達式)
Instrumentation是怎么跟robotium對應上的???其實直接看InstrumenetationTestCase2,會更加清晰,所以Robotium是需要extends InstrumentationTestCase2的。其實東西都是一樣的,就是你要知道包名,然后知道類名,然后通過這個類名去findViewById來獲取到你需要的控件ID,之后調用方法對這個控件進行操作(包括sendPointSync等注入事件、runOnMainSync、runOnUiThread方法等來操作控件),之后根據當前控件的狀態,與你預期想要的狀態做一個對比,就可以知道是否達到了想到的結果。另外,還需要在AndroidManifest.xml中進行<Instrumentation>節點的配置,用以告訴ActivityManager要用什么TestRunner。
demo2和demo3:
instrumentation.sendKeyDownUPSync詳解
sendPointerSync方法(能夠產生手指操作控件的響應效果)
MotionEvent
一個Error的處理:java.lang.SecurityException:Injecting to another application requires INJECT_EVENT permission
解決方案:直接在AndroidManifest.xml中進行配置,如果出現類似的這種涉及到perssion的問題,也是類似,直接在Manifest.xml中配置即可,應該都能解決。
四、Instrumentation類API基礎
1、callActivityOnCreate(Activity activity, Bundle icicle)
說明:Perform calling of an activity's onCreate(Bundle) method
一個activity的onCreate(Bundle savedInstanceState)方法,這個Bundle對象是用來存儲Activity的狀態,比如Activity被stop但不是destory時,這個對象就用上了,之后再resume回來時,就要用到這個Bundle對象來恢復之前的狀態,比較像遞歸里面的堆棧信息的存儲
2、getContext()
說明:得到上下文的一個引用,就可以進一步得到view、windows、控件
3、startActivitySync()
說明:以同步方式start一個Activity,即這是一個阻塞性的方法,必須要start起這個Activity之后,返回了結果,然后程序才能繼續往下走
所謂同步:就是發出一個請求后什么事都不做,一直等待請求返回后才會繼續做事;
所謂異步:就是發出請求后繼續去做其他事,這個請求處理完成后會通知你,這時候就可以處理這個回應了。
4、sendKeyDownUpSync(int key)
downup的點擊事件,通過對一些系統按鍵的操作來完成。比如KeyEvent.KEYCODE_MENU、KeyEvent.KEYCODE_HOME等
5、sendPointerSync(MotionEvent event)
發送一個具體的點觸事件,MotionEvent有obtain方法,可以針對具體的Down或者UP事件進行操作,在某一個特定的坐標位置,通過這個能夠看到測試case時,程序上會出現被點擊選中的陰影效果,而直接調用button.performClick()方法是沒有這個效果的。
金陽光測試 |
新浪微博:金陽光woody |
網站地址 |
1、百度搜:金陽光測試 2、官網:www.goldensunshine.cc |
微信公眾號 |
|