1. 程式人生 > >記Android R(SDK=30)系統執行UiAutomator1.0異常

記Android R(SDK=30)系統執行UiAutomator1.0異常

最近Android釋出了AndroidStudio 3.6穩定版,升級後明顯能體驗到好多細節的提升,最大的提升莫過於可以建立Android R預覽版的模擬器了,並且模擬器可以設定多個尺寸的螢幕。Android R的xm6模擬器可以直接執行arm架構的程式,以後開發過程中再也不用為測試機擔憂了。但是在執行UiAutomator1指令碼時就存在了不相容問題。 ### 異常情況 但是在使用Android R模擬器進行開發工作中發現執行UiAutomator1.0指令碼出現如下異常: ``` Warning: This version of UI Automator is deprecated. New tests should be written using UI Automator 2.0 which is available as part of the Android Testing Support Library. See https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html for more details. INSTRUMENTATION_STATUS: stream= Test results for WatcherResultPrinter=Test run aborted due to unexpected exception: Failed resolution of: Landroid/test/RepetitiveTest; java.lang.NoClassDefFoundError: Failed resolution of: Landroid/test/RepetitiveTest; at com.android.uiautomator.testrunner.UiAutomatorTestRunner$WatcherResultPrinter.startTest(UiAutomatorTestRunner.java:297) at junit.framework.TestResult.startTest(TestResult.java:168) at junit.framework.TestResult.run(TestResult.java:119) at junit.framework.TestCase.run(TestCase.java:129) at com.android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160) at com.android.uiautomator.testrunner.UiAutomatorTestRunner.run(UiAutomatorTestRunner.java:96) at com.android.commands.uiautomator.RunTestCommand.run(RunTestCommand.java:91) at com.android.commands.uiautomator.Launcher.main(Launcher.java:83) at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method) at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:396) Caused by: java.lang.ClassNotFoundException: android.test.RepetitiveTest ... 10 more Time: 0.039 OK (1 test) INSTRUMENTATION_STATUS: shortMsg=Failed resolution of: Landroid/test/RepetitiveTest; INSTRUMENTATION_STATUS_CODE: -1 ``` ### 異常觸發流程 通過分析發現是因為找不到**Landroid/test/RepetitiveTest**類檔案。那麼分析一下堆疊資訊看異常具體出現在哪裡? 在執行UiAutomator1.0測試用例時,是在UiAutomatorTestRunner類中初始化測試資源並執行測試用例的。所以對異常堆疊資訊的分析從UiAutomatorTestRunner類開始。 **com.android.uiautomator.testrunner.UiAutomatorTestRunner.run(UiAutomatorTestRunner.java:96)**原始碼如圖,可以看到此處不存在異常行為,需要定位下一個堆疊資訊 ![](https://img2020.cnblogs.com/blog/668433/202003/668433-20200318230730249-387871394.png) **com.android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160)** 通過分析原始碼會發現是遍歷執行測試用例時產生的異常,並且此處是 ![](https://img2020.cnblogs.com/blog/668433/202003/668433-20200318230756060-1941987395.png) **junit.framework.TestResult.startTest** 僅僅呼叫了WatcherResultPrinter#startTest方法,所以需要繼續定位異常原因 ![](https://img2020.cnblogs.com/blog/668433/202003/668433-20200318230815508-1706678781.png) **com.android.uiautomator.testrunner.UiAutomatorTestRunner$WatcherResultPrinter.startTest(UiAutomatorTestRunner.java:297)**是真正觸發異常的位置,可以看到第一次引用android.test.RepetitiveTest介面檔案時產生了**java.lang.NoClassDefFoundError:**異常資訊。 ![](https://img2020.cnblogs.com/blog/668433/202003/668433-20200318230823823-133155021.png) ### 定位問題原因 通過上述堆疊呼叫鏈發現觸發異常時還沒有執行測試用例,所以這個異常應該是出現在framework層面。由於執行環境是Android R預覽版,無法查閱對應的原始碼,所以無法斷定為系統bug還是Android R系統開始不再支援uiautomator1.0測試服務。 對於採用uiautomator1.0測試框架的業務線需要提前對相關技術進行調研,可以提早設計應對方案。通過上文可以看到,在拋異常時程式已經初始化了uiautomator1.0測試環境,所以要實現uiautomator1.0相容Android R執行時自己註冊測試服務並管理用例即可。 想要了解Uiautomator執行原理可以參考[Uiautomator 專案搭建與實現原理](https://testerhome.com/article