【问题标题】:How to disable the new Autofill feature from Android Oreo for espresso tests如何从 Android Oreo 禁用新的自动填充功能以进行浓缩咖啡测试
【发布时间】:2018-03-30 11:27:39
【问题描述】:

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

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

一些图片:

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

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

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

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

使用AutofillManager#disableAutofillServices() 只会禁用#2。对话框,但 #3。还在。

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

【问题讨论】:

  • 每删除一个答案,设置 > 系统 > 高级 > 自动填充服务 > 设置为“无”。
  • @CommonsWare 我无法从诸如 firebase 之类的云端访问设备上的设置,我需要在测试运行之前从代码中禁用这些设置
  • 对我来说(使用 Android 8.0.0),它位于设置 > 系统 > 语言和输入 > 高级 > 自动填充服务
  • 你找到答案了吗?同样的问题
  • 我不认为这是一种好的做法,您修改了生产代码以使其可测试,并且增加了可能失败的风险以及有关测试存在的知识,请记住这一点未来

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


【解决方案1】:

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

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

用法:

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

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

【讨论】:

  • 它删除了“点按让 Google”对话框,但仍显示“使用 GOOGLE 将密码保存到 AUTOFILL”对话框。
  • 我没有 O 设备,并且在模拟器中找不到“使用 Google 自动填充”应用程序。我认为您可以在执行检测测试时尝试通过 adb shell 命令 (how?) 禁用该应用程序:adb shell pm disable package.name.of.autofill.with.google
  • 您可以在Settings 中找到它,用于 Android O 模拟器。
【解决方案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();
}

【讨论】:

  • 只是为了这个目的而更改我的应用程序中的所有EditText 感觉很糟糕,但谢谢
【解决方案3】:

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

当发生以下情况之一时,上下文就结束了:

  1. commit() 被调用或所有可保存的视图都消失了。
  2. cancel() 被调用。

从任何线程调用它的方法都是安全的。

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

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

【讨论】:

  • 请阅读问题,我已经说过有一种情况不起作用
【解决方案4】:

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

【讨论】:

  • 最后一个adb shell settings put secure autofill_service null 成功了!谢谢人
  • 你能在“... autofill_service null”之后添加代码以再次启用它吗:)
  • 我启用它为“com.google.android.gms/com.google.android.gms.autofill.service.AutofillService”更改“null”,谢谢:)
【解决方案5】:

我很幸运在 Espresso 测试期间禁用自动填充,并在输入文本时应用自定义 ViewAction。

            .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();
                            }
                        }
                    });

【讨论】:

    【解决方案6】:

    基于@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())
    

    【讨论】:

      【解决方案7】:

      下面的sn-p可以用来忽略新的android建议:

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

        • 如果您可以访问您的设备,但不适用于测试设备场和更自动化的东西,则此方法有效,请阅读问题文本。
        猜你喜欢
        • 1970-01-01
        • 2018-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多