使用sdk 26
在Android设备上运行测试会导致它们失败,因为当espresso尝试点击它们时,新的Autofill功能会隐藏字段。
我在firebase测试实验室运行我的测试,所以我不能在我的测试设备上手动禁用它们。
一些图片:
Espresso无法点击现在的密码字段,因为自动填充对话框隐藏了我的字段和fail
。
使用AutofillManager#disableAutofillServices()
只禁用#2。对话但#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
根据文档,您可以使用AutofillManager#disableAutofillServices()
API禁用自动填充服务:
如果调用此API的应用启用了自动填充服务,则会禁用它们。
用法:
val autofillManager: AutofillManager = context.getSystemService(AutofillManager::class.java)
autofillManager.disableAutofillServices()
您可以在测试的@Before
步骤中执行此操作。
我很幸运在Espresso测试期间禁用自动填充,只要输入文本,就会应用自定义ViewActions。
.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();
}
}
});
基于@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();
}
}
}
}
并且,在您的代码中,当您需要为editText密码禁用自动填充时...
editTextPassword.perform(..., ViewActions.closeSoftKeyboard(), DisableAutofillAction())
根据文档:当视图聚焦并且是数据集的一部分时。通过registerCallback(AutofillCallback)注册AutofillManager.AutofillCallback,可以在显示可供性时通知应用程序。当用户从示能表中选择数据集时,通过调用自动填充(AutofillValue)或自动填充(SparseArray)自动填充数据集中存在的所有视图。
然后在出现以下情况之一时完成上下文:
从任何线程调用其方法是安全的。
必须使用带有参数AutofillManager.class的Context.getSystemService(Class)获取此类的实例。
使用:disableAutofillServices()方法禁用该服务。
以下代码段可用于忽略新的android建议:
getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
测试时禁用自动填充。在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();
}