如何从Android Oreo中禁用espresso测试的新自动填充功能

时间:2017-10-18 14:34:59

标签: android testing android-espresso android-testing android-autofill-manager

使用sdk 26在Android设备上运行测试会导致它们失败,因为新的Autofill功能会在espresso尝试点击它们时隐藏字段。

我在firebase测试实验室运行测试,因此无法在我的测试设备上手动禁用它们。

一些图片:

1。在单击用户名字段之前,密码是可见的。

enter image description here

2。单击用户名字段后,此自动填充对话框将隐藏密码字段:

enter image description here

3。登录后,它会显示另一个“填充”对话框:

enter image description here

Espresso无法点击现在的密码字段,因为自动填充对话框隐藏了我的字段fail

使用AutofillManager#disableAutofillServices()仅禁用#2。对话但#3。还在那里。

如何在测试设备上禁用自动填充?

8 个答案:

答案 0 :(得分:6)

根据文档,您可以使用AutofillManager#disableAutofillServices() API禁用自动填充服务:

  

如果调用此API的应用启用了自动填充服务,则会禁用它们。

用法:


    val autofillManager: AutofillManager = context.getSystemService(AutofillManager::class.java)
    autofillManager.disableAutofillServices()

您可以在测试的@Before步骤中执行此操作。

答案 1 :(得分:3)

adb shell pm disable com.google.android.gms/com.google.android.gms.autofill.service.AutofillService

这应禁用自动填充服务。与手动关闭系统设置中的自动填充服务相同。它至少在模拟器上工作。但这需要root访问权限。

禁用自动填充服务的另一种方法是更改​​autofill_service设置。

adb shell settings put secure autofill_service null

答案 2 :(得分:3)

我很幸运在每次输入文本时都应用自定义ViewAction的Espresso测试期间禁用自动填充功能。

            .onView(...)
            .perform(
                    new ViewAction() {
                        @Override
                        public Matcher<View> getConstraints() {
                            return Matchers.any(View.class);
                        }

                        @Override
                        public String getDescription() {
                            return "Marking view not important for autofill";
                        }

                        @Override
                        public void perform(UiController uiController, View view) {
                            // Required to disable autofill suggestions during tests on API 26+
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                view.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
                            }
                        }
                    })
            .perform(click())
            .perform(clearText())
            .perform(typeText(textToType))
            .perform(
                    new ViewAction() {
                        @Override
                        public Matcher<View> getConstraints() {
                            return Matchers.any(View.class);
                        }

                        @Override
                        public String getDescription() {
                            return "Dismissing autofill picker";
                        }

                        @Override
                        public void perform(UiController uiController, View view) {
                            // Required to dismiss the autofill picker during tests on API 26+
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                AutofillManager autofillManager =
                                        view.getContext()
                                                .getSystemService(AutofillManager.class);
                                if (autofillManager != null) autofillManager.cancel();
                            }
                        }
                    });

答案 3 :(得分:2)

基于@Alan K解决方案的替代代码组织。

创建类DisableAutofillAction:

public class DisableAutofillAction implements ViewAction {

    @Override
    public Matcher<View> getConstraints() {
        return Matchers.any(View.class);
    }

    @Override
    public String getDescription() {
        return "Dismissing autofill picker";
    }

    @Override
    public void perform(UiController uiController, View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            AutofillManager autofillManager = view.getContext().getSystemService(AutofillManager.class);

            if (autofillManager != null) {
                autofillManager.cancel();
            }
        }
    }
}

而且,在您的代码中,当您需要为editTextPassword禁用自动填充...

editTextPassword.perform(..., ViewActions.closeSoftKeyboard(), DisableAutofillAction())

答案 4 :(得分:0)

根据文档:       当视图聚焦并且是数据集的一部分时。通过registerCallback(AutofillCallback)注册AutofillManager.AutofillCallback,可以在显示可供性时通知应用程序。当用户从示能表中选择数据集时,通过调用自动填充(AutofillValue)或自动填充(SparseArray)自动填充数据集中存在的所有视图。

当出现以下情况之一时,上下文结束:

  1. 调用commit()或者所有可保存的视图都消失了。
  2. 取消()被调用。
  3. 从任何线程调用其方法是安全的。

    必须使用带有参数AutofillManager.class的Context.getSystemService(Class)获取此类的实例。

    使用:disableAutofillServices()方法来禁用该服务。

答案 5 :(得分:0)

以下代码段可用于忽略新的android建议:

getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);

答案 6 :(得分:-1)

在您的设备内,转到此路线 设置>系统>语言和输入法>高级>自动填充服务并取消

答案 7 :(得分:-2)

测试时禁用自动填充。在gradle中定义TestRunner类

defaultConfig {
    testInstrumentationRunner "com.cover.android.TestRunner"
}

然后

public class TestRunner extends AndroidJUnitRunner {

@Override
public void onCreate(Bundle arguments) {
    super.onCreate(arguments);
    CustomEditText.TESTING = TRUE;
    }

然后使用EditText的自定义版本

public class CustomEditText extends AppCompatEditText {
public static boolean TESTING = false;
public CustomEditText(Context context) {
    super(context);
}

@Override
public int getAutofillType() {
    return TESTING? AUTOFILL_TYPE_NONE : super.getAutofillType();
}