上一篇文章我們已經知道testcases目錄中xml設定檔讀取出來後的形式,繼續往下看:
然後把xml對應的TestPackageDef儲存到Map<String, TestPackageDef>中,所以我們可以這樣說,TestPackageDef就代表了一個testcases目錄下的xml檔案。所以有多少個xml檔案就有多少個TestPackageDef對象,然後將這些對象儲存到map中。key值為xml的appPackageName屬性值。當所有的xml檔案都配置完成後,我們就回到了buildTestsToRun方法中:
這個時候調用了getTestPackagesToRun,這個方法是從剛才得到的testRepo對象中篩選出本次任務需要跑的ITestPackageDef列表。再根據該列表組裝List<TestPackage>
對象testPkgList並返回。
然乎根據參數來添加發生錯誤時的操作:
儲存bugreport資訊
儲存截圖
儲存logcat system的資訊
然後找到要安裝的apk和執行完任務後要卸載的包名:
這是根據xml中targetBinaryName屬性對應的值找到apk名和targetNameSpace屬性找到要卸載的包名。然後安裝這些apk,並擷取手機裝置資訊。實際上是通過安裝TestDeviceSetup.apk,然後運行Instrumentation的case來擷取資訊的。擷取完資訊以後,會判斷是否需要重啟,只有當要執行的case包大於1且mDisableReboot為false時才重啟裝置。然後是迴圈執行測試工作,以包為單位執行,執行的核心為test.run(filter);
先將包含測試的apk安裝到裝置中,然後運行case,最後刪除case包。我們來看看刪除的case包到底是什麼。
原來apk安裝後,android系統是通過其包名來定位apk的,所以卸載的時候肯定要用包名。先來再來回頭看super.run(listener);
先通過DDM的RemoteAndroidTestRunner來建立測試的runner,然後設定一些基本參數,就可以調用doTestRun方法來進行實際的測試。
先獲得要測試的case資訊。經過一系列跳來跳去跳來跳去,最後到了TestDevice中:
最後到執行case,執行完以後會判斷是否成功發送了命令,如果沒有就要重連裝置。最後講一下performDeviceAction這個方法:
private boolean performDeviceAction(String actionDescription, final DeviceAction action, int retryAttempts) throws DeviceNotAvailableException {// 如果成功直接返回,如果失敗就要重試for (int i = 0; i < retryAttempts + 1; i++) {try {return action.run();} catch (TimeoutException e) {logDeviceActionException(actionDescription, e);} catch (IOException e) {logDeviceActionException(actionDescription, e);} catch (InstallException e) {logDeviceActionException(actionDescription, e);} catch (SyncException e) {logDeviceActionException(actionDescription, e);// a SyncException is not necessarily a device communication// problem// do additional diagnosisif (!e.getErrorCode().equals(SyncError.BUFFER_OVERRUN) && !e.getErrorCode().equals(SyncError.TRANSFER_PROTOCOL_ERROR)) {// this is a logic problem, doesn't need recovery or to be// retriedreturn false;}} catch (AdbCommandRejectedException e) {logDeviceActionException(actionDescription, e);} catch (ShellCommandUnresponsiveException e) {CLog.w("Device %s stopped responding when attempting %s", getSerialNumber(), actionDescription);}// TODO: currently treat all exceptions the same. In future consider// different recovery// mechanisms for time out's vs IOExceptionsrecoverDevice();}if (retryAttempts > 0) {throw new DeviceUnresponsiveException(String.format("Attempted %s multiple times " + "on device %s without communication success. Aborting.",actionDescription, getSerialNumber()));}return false;
上面的寫法會在case執行過程中出現異常的話,會有重試機制。但前提是retryAttempts這個變數的值要大於0。