最近 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) 源码如图, 可以看到此处不存在异常行为, 需要定位下一个堆栈信息
com.Android.uiautomator.testrunner.UiAutomatorTestRunner.start(UiAutomatorTestRunner.java:160) 通过分析源码会发现是遍历执行测试用例时产生的异常, 并且此处是
junit.framework.TestResult.startTest 仅仅调用了 WatcherResultPrinter#startTest 方法, 所以需要继续定位异常原因
com.Android.uiautomator.testrunner.UiAutomatorTestRunner$WatcherResultPrinter.startTest(UiAutomatorTestRunner.java:297) 是真正触发异常的位置, 可以看到第一次引用 Android.test.RepetitiveTest 接口文件时产生了 java.lang.NoClassDefFoundError: 异常信息.
定位问题原因
通过上述堆栈调用链发现触发异常时还没有执行测试用例, 所以这个异常应该是出现在 framework 层面. 由于运行环境是 Android R 预览版, 无法查阅对应的源码, 所以无法断定为系统 bug 还是 Android R 系统开始不再支持 uiautomator1.0 测试服务.
对于采用 uiautomator1.0 测试框架的业务线需要提前对相关技术进行调研, 可以提早设计应对方案. 通过上文可以看到, 在抛异常时程序已经初始化了 uiautomator1.0 测试环境, 所以要实现 uiautomator1.0 兼容 Android R 运行时自己注册测试服务并管理用例即可.
想要了解 Uiautomator 执行原理可以参考 Uiautomator 项目搭建与实现原理 https://testerhome.com/articles/20078
来源: https://www.cnblogs.com/walker-world/p/12521155.html