Espresso - Set SeekBar

2019-03-18 23:06发布

does anybody know, how to set a seekBar to a specific value or just a click on that view on Espresso UI Testing ?

I just get an exception: Error performing 'single click' on view with id...

onView(withId(R.id.FilterPriceMax)).perform(click());

5条回答
男人必须洒脱
2楼-- · 2019-03-18 23:31

You might want to give the following code a try:

First you could match the SeekBar with its class name:

onView(withClassName(Matchers.equalTo(SeekBar.class.getName()))).perform(setProgress(progress));

where setProgress(final int progress) is a ViewAction you defined as:

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);
            }
        };
    }
查看更多
闹够了就滚
3楼-- · 2019-03-18 23:34

I use a swipe-action to perform an actual swipe on the SeekBar. This makes sure the callback method (SeekBar.OnSeekBarChangeListener. onProgressChanged) is called with fromUser set to true. It is also more in the line of click testing.

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 };
    }
}
查看更多
Root(大扎)
4楼-- · 2019-03-18 23:36

I have used this to do some basic testing on seekbar UI components if you don't require specific values. It assumes the 'check()' is based on a 0-100 percentage.

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")));
查看更多
混吃等死
5楼-- · 2019-03-18 23:45

I have a custom Seekbar, and also I have multiple Seekbars in my View. I managed do my test with this code below:

onView(withId(R.id.my_seek_bar)).perform(setProgress(10));

and

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);
            }
        };
    }
查看更多
Bombasti
6楼-- · 2019-03-18 23:47

In case you want to check the progress value

  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;
      }
    };
  }
查看更多
登录 后发表回答