有人知道,在Espresso UI测试中,如何将SeekBar设置为特定值或仅通过单击该视图来实现?
我只是收到一个异常:在ID为...的视图上执行“单击”时出错。
onView(withId(R.id.FilterPriceMax)).perform(click());
有人知道,在Espresso UI测试中,如何将SeekBar设置为特定值或仅通过单击该视图来实现?
我只是收到一个异常:在ID为...的视图上执行“单击”时出错。
onView(withId(R.id.FilterPriceMax)).perform(click());
您可能想尝试以下代码:
首先,您可以使用其类名将 SeekBar
进行匹配:
onView(withClassName(Matchers.equalTo(SeekBar.class.getName()))).perform(setProgress(progress));
setProgress(final int progress)是你定义的一个ViewAction:
public static ViewAction setProgress(final int progress) {
return new ViewAction() {
@Override
public void perform(UiController uiController, View view) {
SeekBar seekBar = (SeekBar) view;
seekBar.setProgress(progress);
}
@Override
public String getDescription() {
return "Set a progress on a SeekBar";
}
@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(SeekBar.class);
}
};
}
我有一个自定义的SeekBar,并且在我的View中有多个SeekBar。我用下面的代码成功地进行了测试:
onView(withId(R.id.my_seek_bar)).perform(setProgress(10));
和
public static ViewAction setProgress(final int progress) {
return new ViewAction() {
@Override
public void perform(UiController uiController, View view) {
((MyCustomSeekBar) view).setSelectedProgress(progress);
//or ((SeekBar) view).setProgress(progress);
}
@Override
public String getDescription() {
return "Set a progress";
}
@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(RangeSeekBar.class);
}
};
}
我使用滑动操作在SeekBar
上执行实际的滑动。这可以确保回调方法(SeekBar.OnSeekBarChangeListener.onProgressChanged
)被调用时fromUser
设置为true。这也更符合点击测试的要求。
public static ViewAction scrubSeekBarAction(int progress) {
return actionWithAssertions(new GeneralSwipeAction(
Swipe.SLOW,
new SeekBarThumbCoordinatesProvider(0),
new SeekBarThumbCoordinatesProvider(progress),
Press.PINPOINT));
}
private static class SeekBarThumbCoordinatesProvider implements CoordinatesProvider {
int mProgress;
public SeekBarThumbCoordinatesProvider(int progress) {
mProgress = progress;
}
private static float[] getVisibleLeftTop(View view) {
final int[] xy = new int[2];
view.getLocationOnScreen(xy);
return new float[]{ (float) xy[0], (float) xy[1] };
}
@Override
public float[] calculateCoordinates(View view) {
if (!(view instanceof SeekBar)) {
throw new PerformException.Builder()
.withViewDescription(HumanReadables.describe(view))
.withCause(new RuntimeException(String.format("SeekBar expected"))).build();
}
SeekBar seekBar = (SeekBar) view;
int width = seekBar.getWidth() - seekBar.getPaddingLeft() - seekBar.getPaddingRight();
double progress = mProgress == 0 ? seekBar.getProgress() : mProgress;
int xPosition = (int) (seekBar.getPaddingLeft() + width * progress / seekBar.getMax());
float[] xy = getVisibleLeftTop(seekBar);
return new float[]{ xy[0] + xPosition, xy[1] + 10 };
}
}
scrubSeekBarAction
之后的进度值与您设置的不同,那么在“scrub…”之前(以及之后)使用Thread.sleep(1000)
似乎有所帮助。我猜这类似于“perform(click())执行长按”的问题。 - allofmex如果您想要检查进度值
public static Matcher<View> withProgress(final int expectedProgress) {
return new BoundedMatcher<View, SeekBar>(SeekBar.class) {
@Override
public void describeTo(Description description) {
description.appendText("expected: ");
description.appendText(""+expectedProgress);
}
@Override
public boolean matchesSafely(SeekBar seekBar) {
return seekBar.getProgress() == expectedProgress;
}
};
}
如果您不需要特定的值,我已经使用它来对seekbar UI组件进行基本测试。它假设'check()'是基于0-100百分比的。
onView(withId(R.id.yourSeekBar)).perform(new GeneralClickAction(Tap.SINGLE, GeneralLocation.CENTER_LEFT, Press.FINGER));
onView(withId(R.id.yourSeekBarUserFeedback)).check(matches(withText("0")));
onView(withId(R.id.yourSeekBar)).perform(new GeneralClickAction(Tap.SINGLE, GeneralLocation.CENTER, Press.FINGER));
onView(withId(R.id.yourSeekBarUserFeedback)).check(matches(withText("50")));
onView(withId(R.id.yourSeekBar)).perform(new GeneralClickAction(Tap.SINGLE, GeneralLocation.CENTER_RIGHT, Press.FINGER));
onView(withId(R.id.yourSeekBarUserFeedback)).check(matches(withText("100")));
GeneralClickAction()
接受 3 个参数的声明已被弃用。现在我们建议使用接受 5 个参数的 GeneralClickAction()
,如此处所示:https://dev59.com/gmEh5IYBdhLWcg3wpE3w - Mr-IDE
fromUser
,因此如果您使用该标志,它将无法工作。 - jluiz20fromUser
标志 :( - Quintin Balsdon