我有一个
MaterialDatePicker
对话框,我想编写一个选择日期的 Espresso 测试。不幸的是,我不能使用 PickerActions
来实现这一点。我正在寻找类似的东西:
onView(withClassName(Matchers.equalTo(DatePicker.class.getName()))).perform(PickerActions.setDate(year, monthOfYear, dayOfMonth));
有人对如何解决这个问题有任何想法吗?
提前致谢!
我发现这个答案隐藏在上面链接的问题中,您可能会发现它对于在InputMode为
INPUT_MODE_TEXT
时设置日期很有用。
public static void setDate(LocalDate date){
onView(withTagValue((Matchers.is((Object) ("TOGGLE_BUTTON_TAG"))))).perform(click());
onView(withId(com.google.android.material.R.id.mtrl_picker_text_input_date)).perform(replaceText(date.format(DateTimeFormatter.ofPattern("M/d/yy"))));
}
public static void setTime(LocalTime time){
onView(withId(com.google.android.material.R.id.material_timepicker_mode_button)).perform(click());
onView(withId(com.google.android.material.R.id.material_hour_text_input)).perform(click());
onView(allOf(isDisplayed(), withClassName(is(AppCompatEditText.class.getName())))).perform(replaceText(time.format(DateTimeFormatter.ofPattern("hh"))));
onView(withId(com.google.android.material.R.id.material_minute_text_input)).perform(click());
onView(allOf(isDisplayed(), withClassName(is(AppCompatEditText.class.getName())))).perform(replaceText(time.format(DateTimeFormatter.ofPattern("mm"))));
}
就非常紧密地依赖 ids 而不改变而言,这绝对是很糟糕的,但它是有效的。
如果您想选择输入模式为
INPUT_MODE_CALENDAR
的日期,那么这对我有用:
onView(
// the date you are selecting must be visible for this to work
withContentDescription("Mon, Jan 1, 1990")
).inRoot(RootMatchers.isDialog())
.perform(click())
onView(withId(com.google.android.material.R.id.confirm_button))
.perform(click())
您可以通过单击“材料日期选择器”布局中的相应按钮来进一步扩展此答案以选择不同的月/日/年。您可以在源代码中寻找 ids。
我只想添加@Chantell Osejo 的评论。有些日期会有不同的内容描述,如下所示:
"Mon, Jan 1, 2024"
"Fri, Dec 29"
"Today Thu, Dec 28"
如果您使用
MaterialDatePicker.dateRangePicker()
,当您选择开始日期时,所选开始日期的内容描述将是例如"Start date Mon, Jan 1, 2024"
。
这是我根据@Chantell Osejo 的评论制作的匹配器。仍然需要改进,请随时发表评论。
fun withDate(date: Date): Matcher<View> {
fun areDatesEqual(calendar1: Calendar, calendar2: Calendar): Boolean {
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) &&
calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) &&
calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
}
fun areYearsEqual(calendar1: Calendar, calendar2: Calendar): Boolean {
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
}
val now = Calendar.getInstance()
val selectedDate = Calendar.getInstance().apply {
time = date
}
val isToday = areDatesEqual(now, selectedDate)
val areYearsEqual = areYearsEqual(now, selectedDate)
val dateFormat = if (areYearsEqual) {
SimpleDateFormat("EEE, MMM d")
} else {
SimpleDateFormat("EEE, MMM d, yyyy")
}
val finalDate = if (isToday) {
"Today ${dateFormat.format(date)}"
} else {
dateFormat.format(date)
}
return withContentDescription(finalDate)
}
用途:
val tomorrowCalendar = Calendar.getInstance().apply {
add(Calendar.DAY_OF_MONTH, 1)
}
onView(withDate(tomorrowCalendar.time))
.inRoot(RootMatchers.isDialog())
.perform(click())