如何使用 espresso 自动化数字选择器。我想使用 espresso 在 timePicker 中设置特定时间。
6 回答
要通过类名匹配视图,您可以简单地使用:
onView(withClassName(Matchers.equalTo(TimePicker.class.getName())));
拥有 ViewInteraction 对象后,您可以在其上设置一个值,定义和使用 ViewAction,如下所示:
public static ViewAction setTime(final int hour, final int minute) {
return new ViewAction() {
@Override
public void perform(UiController uiController, View view) {
TimePicker tp = (TimePicker) view;
tp.setCurrentHour(hour);
tp.setCurrentMinute(minute)
}
@Override
public String getDescription() {
return "Set the passed time into the TimePicker";
}
@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(TimePicker.class);
}
};
}
匹配视图,然后执行操作:
ViewInteraction numPicker = onView(withClassName(Matchers.equalTo(NumberPicker.class.getName())));
numPicker.perform(setNumber(1));
创建一个 ViewAction 来设置数字:
public static ViewAction setNumber(final int num) {
return new ViewAction() {
@Override
public void perform(UiController uiController, View view) {
NumberPicker np = (NumberPicker) view;
np.setValue(num);
}
@Override
public String getDescription() {
return "Set the passed number into the NumberPicker";
}
@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(NumberPicker.class);
}
};
}
接受的答案存在问题:它不会在更改事件时触发。所以(如果你需要的话)你不能测试你的视图是否对这个变化事件做出反应。
下面的代码(kotlin)无论如何都不酷,但我认为这是唯一的方法。
fun setValue(value: Int): ViewAction {
return object : ViewAction {
override fun getDescription(): String {
return "set the value of a " + NumberPicker::class.java.name
}
override fun getConstraints(): Matcher<View> {
return ViewMatchers.isAssignableFrom(NumberPicker::class.java)
}
// the only way to fire onChange event is to call this private method
override fun perform(uiController: UiController?, view: View?) {
val numberPicker = view as NumberPicker
val setValueMethod = NumberPicker::class.java.getDeclaredMethod(
"setValueInternal",
Int::class.java,
Boolean::class.java
)
setValueMethod.isAccessible = true
setValueMethod.invoke(numberPicker, value, true)
}
}
}
我使用了内置的 TimePickerDialog。
(科特林)
fun setAlarmTime(){
val calendar = Calendar.getInstance()
onView(isAssignableFrom(TimePicker::class.java)).perform(
PickerActions.setTime(
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE) + 2
)
)
onView(withText("OK")).perform(click())
}
首先,您应该打开 TimePickerDialog,然后使用此代码。时间将为当前时间 + 2 分钟。设置完成后,单击“确定”按钮。
对于稍后查看此问题的人(如我),这可能会有所帮助:DateTimePickerTest使用PickerActions。PickerActions 允许这样的日期选择器代码(Java):
onView(withClassName(Matchers.equalTo(DatePicker.class.getName()))).perform(PickerActions.setDate(year, month + 1, day));
或者对于时间选择器(Kotlin):
onView(withClassName(Matchers.equalTo(TimePicker::class.java.name))).perform(PickerActions.setTime(0, 10))
我找到了解决问题的方法,即 Luigi Massa Gallerano 的解决方案不会触发更改侦听器。
除了他的方法之外,您还需要添加一种包装方法,每次向上和向下滑动一次。这会触发 changeListener,尽管之前的值当然会丢失。
fun setNumberPickerValue(viewInteraction: ViewInteraction, value: Int) {
viewInteraction.perform(setValue(value))
viewInteraction.perform(GeneralSwipeAction(Swipe.SLOW, GeneralLocation.TOP_CENTER, GeneralLocation.BOTTOM_CENTER, Press.FINGER))
SystemClock.sleep(50)
viewInteraction.perform(GeneralSwipeAction(Swipe.SLOW, GeneralLocation.BOTTOM_CENTER, GeneralLocation.TOP_CENTER, Press.FINGER))
SystemClock.sleep(50)
}
给出的示例是使用 NumberPicker 和 Kotlin,但原则上是相同的。