UiAutomator初体验(中)

事实上,如何上手编写最基本的UiAutomator测试,官网 上已经给出了设置步骤和简单的代码示例,只是没有从零开始介绍怎么创建一个完整的测试而已,所以我们可以基于官网文档,写一个可以在模拟器上运行的测试。

添加依赖

回到上篇博客创建好的测试项目,在app模块的build.gradle文件中,加上UiAutomator库的依赖:

1
2
3
4
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}

添加之后Android Studio可能不会立刻下载依赖,所以为了确保可以使用uiautomator,需要在下图手动Apply一下:

下载依赖

定位元素

UI测试的第一步当然是定位元素,uiautomatorviewer工具可以做到这一点,它位于 android-sdk/tools/bin/ 目录,android-sdk就是下图中的sdk路径:

sdk location
打开终端,定位到上述目录中,然后运行uiautomatorviewer:

运行uiautomatorviewer
如果上篇博客的环境都准备好了,就能打开uiautomatorviewer窗口,如果有已启动的设备,这里我打开了一个 安卓模拟器 ,点击窗口左上角第二个按钮,就能获取设备当前页面的screenshot,右侧是页面元素信息,通过这些信息,我们就可以定位元素了。
UiAutomator提供了findObject()方法定位UiObject元素,以定位上图页面底部Login按钮为例:

Kotlin:

1
2
3
val loginButton: UiObject = device.findObject(
UiSelector().text("Login").className("android.widget.TextView")
)

Java:

1
2
3
UiObject loginButton = device.findObject(new UiSelector()
.text("Login")
.className("android.widget.TextView"));

编写代码

接下来我们就可以编写代码测试App了,我还是用了 之前文章 里的测试App,可以在 这里 下载,然后把它安装到模拟器里。
我们来编写最简单的两个Case,登录和注册。

登录和注册页面

首先是登录,要实现登录操作,我们要切换到登录页面,之后输入邮箱和密码,再点击登录即可。
然后是注册,需要先切换到登录页面,再切换到注册tab页,之后输入邮箱、密码、确认密码字段,最后点击注册即可。

这里我只贴出一个步骤,是去打开app的登录页面,就使用上面的元素定义,其它步骤都可以参考这个完成:

打开登录页面测试步骤
其中,launchApp方法依然是 官网提供 的,先定义了一个device对象,通过该对象连接设备,然后再利用PackageName打开对应的App,最后我们定位元素并点击进入登录页面。
设备当前打开App的PackageName可以通过以下命令得到:

1
adb shell dumpsys window | grep -E 'mCurrentFocus'

这就是我们使用Ui Automator编写的第一个可以运行的测试。

执行测试

有三种方式可以运行Ui Automator测试,第一种是直接在编辑器里点击运行图标:

两个地方都可以点
第二种方式是通过adb shell在命令行运行:

1
adb shell am instrument -w -m -e debug false -e class 'com.example.androidtest.ExampleInstrumentedTest#openLoginPage' com.example.androidtest.test/androidx.test.runner.AndroidJUnitRunner

第三种方式也是在命令行运行,上篇博客提到,因为Ui Automator测试位于androidTest文件夹,是一种插桩测试,所以可以利用gradle直接运行,和mvn test执行测试的道理差不多:

1
./gradlew connectedAndroidTest

后两种运行方式,官网上也给出了 详细介绍 ,并且提供了各个参数的含义。
值得一提的是,用第三种方式运行测试还会生成两个测试结果文件,一个是html格式,在 path_to_your_project/module_name/build/reports/androidTests/connected/ 目录中:

测试报告
另一个是xml格式,在 path_to_your_project/module_name/build/outputs/androidTest-results/connected/ 目录中。

PageObject

尽管我们已经写好了测试,但把所有的步骤都放在一个文件中显然不是good practice,所以我们可以按照Page Object模式将代码进行优化,把before方法、页面元素、操作步骤和测试分开,完成后的代码结构如下:

PageObject
其中,selectors包里是各个页面的元素,pages包则用来存放各个页面的操作方法,公用的方法比如launchApp都放在BasePage里,真正的测试用例则统一放在tests包里,我已将 代码库 上传到了github,不足之处还请大家批评指正。
以下是用三种方式执行测试的视频,直接点击编辑器图标运行大概12秒,用adb运行16秒,gradle运行也不过25秒: