返回 登录
0

在UI测试中处理Android运行时权限

图片描述

几个月前我看了下新的Android权限模型,在引入Marshmallow后变化很大。执行新模型意味着我们需要确保:

  • 查看是否在需要时有所需的权限;

  • 在恰当时向用户请求权限;

  • 正确处理UI上的请求(空状态或数据反馈),以代表所需的权限被通过或拒绝。

在执行以上内容后,Marshmallow与Marshmallow前设备应当都能正常演示与运行。

现在,作为一个优秀的开发人员,所有的功能测试代码你肯定已经编写完成了。不过等一下,请求授权的屏幕相关测试如何了,6.0+的设备能够通过吗?在获得与被拒绝授权的时候,我们如何测试不同的UI状态?

我做了一点在线调查,有时候开发者建议使用adb来获取及撤销权限。但如果我们想要通过应用UI测试真实交互状况的话,这不算个好办法。对我来说也是如此,这些测试算是失败的。

那么,我们能否使用Espresso来完成这项工作呢?很不幸,Espresso不能从应用程序外部访问组件。

幸运的是Testing Support Library有另一个可用框架——UIAutomator。与espresso不同,使用UIAutomator是能与系统应用交互的,也就是说,在需要时我们能够与Permission对话框交互。更棒的是,在UI测试中UIAutomator可以与espresso一同使用。

不过如何运作呢?这种框架提供了一种UiDevice类,在运行该应用的设备上可用来访问并执行操作,还能用来模拟用户在设备上的操作,对执行方向键操作、与通知栏互动之类的事件非常有用。

我们看个屏幕测试的流程图——在设备上显示用户的通讯录列表:

图片描述

  • 启动测试活动,开始测试。

  • 测试开始后,6.0+设备上,应用代码触发访问通讯录的请求。由于尚未授权,会显示对话框请求权限。

  • 下一步,需要通过UIAutomator与授权对话框互动,进行授权或拒绝访问。如果点击“允许”,则需查看通讯录是否正常显示。但如果拒绝访问,UI需要显示空状态,以反映这种情况。

如何执行呢?如果想要在UI测试中进行授权,则需要找到希望点击的相应UiObject。该对象代表着视图,但并未与视图绑定,它包含相关信息,会在运行时与视图匹配,是基于构造函数中UiSelector实例的属性。UiSelector实例是我们测试中,在布局中声明元素的对象,是我们测试的目标。我们可以为这个UiSelector实例设定不同的属性,比如文本值、类名或内容描述。

我们希望与测试交互的UiObject 有许多使用方式,其中一种就是简单的click()。所有一切都可以通过以下代码实现:

private void allowPermissionsIfNeeded()  {
    if (Build.VERSION.SDK_INT >= 23) {
        UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
        if (allowPermissions.exists()) {
            try {
                allowPermissions.click();
            } catch (UiObjectNotFoundException e) {
                Timber.e(e, "There is no permissions dialog to interact with ");
            }
        }
    }
}

拒绝访问的实现也很类似,只要找到合适的“拒绝”文本来替代“允许”。

使用上面的方法,在6.0+的设备上都能按需测试,查看在权限授予与拒绝时UI的相应反应了。很明显这里有个缺陷,就是在系统中的“允许”及/或“拒绝”文本修改后,测试会被打断。

除此之外,UIAutomator的框架还有很多功用,所以在测试中查看相关文档,找出可用内容十分值得,今后说不定会节省你很多时间。

英文来源:Handling Android runtime permissions in UI tests
作者:Joe Birch(@hitherejoe),Android Developer
翻译:孙薇
审校:唐小引(@唐门教主),邮箱:tangxy@csdn.net,欢迎投稿、约稿以及给文章挑错。

评论