1.运行AS的 run->Record Espresso Test, 之后关掉,这一步会自动添加依赖关系
2.在ExampleInstrumentedTest或其他安卓测试类中定义 ↓,Activity为启动Activity
@Rule
public ActivityScenarioRule<MainActivity> activityScenarioRule
= new ActivityScenarioRule<>(MainActivity.class);
3.在代码中使用
onView(withId(R.id.output_view)).perform(actionWithAssertions(new GeneralSwipeAction( Swipe.SLOW, GeneralLocation.CENTER, new CoordinatesProvider() { @Override public float[] calculateCoordinates(View view) { return getCoordinates(view, 0, (int) (400 * Math.random())); } }, Press.FINGER))); onView(withId(R.id.type)).perform(new WaitForView(obj -> withText("S").matches(obj), 100000)); onView(withId(R.id.output_view)).perform(actionWithAssertions(new GeneralSwipeAction( Swipe.SLOW, GeneralLocation.CENTER, new CoordinatesProvider() { @Override public float[] calculateCoordinates(View view) { return getCoordinates(view, 0, (int) (-400 * Math.random())); } }, Press.FINGER))); onView(withId(R.id.type)).perform(new WaitForView(obj -> withText("S").matches(obj), 100000)); onView(withId(R.id.output_view)).perform(actionWithAssertions(new GeneralSwipeAction( Swipe.SLOW, GeneralLocation.CENTER, new CoordinatesProvider() { @Override public float[] calculateCoordinates(View view) { return getCoordinates(view, 0, -400); } }, Press.FINGER))); onView(withId(R.id.type)).perform(new WaitForView(obj -> withText("S").matches(obj), 100000)); testVideosToggleLoop(); IdlingRegistry.getInstance().register(new IdlingResource() { @Override public String getName() { return null; } @Override public boolean isIdleNow() { return false; } @Override public void registerIdleTransitionCallback(ResourceCallback callback) { } }); }
private static float[] getCoordinates(View view, int vertical, int horizontal) { final int[] xy = new int[2]; view.getLocationOnScreen(xy); final float x = xy[0] + (view.getWidth() - 1) / 2 + horizontal; final float y = xy[1] + (view.getHeight() - 1) / 2 + vertical; float[] coordinates = {x, y}; return coordinates; }
4. 等待View的特定状态
/** * This ViewAction tells espresso to wait till a certain view is found in the view hierarchy. * * @param test The id of the view to wait for. * @param timeout The maximum time which espresso will wait for the view to show up (in milliseconds) */ class WaitForView implements ViewAction { private final int timeout; private final Predicate test; WaitForView(Predicate<View> test, int timeout) { super(); this.test = test; this.timeout = timeout; } @Override public Matcher<View> getConstraints() { return Matchers.is(instanceOf(View.class)); } public String getDescription() { return "wait for a specific test; during " + timeout + " millis."; } public void perform(UiController uiController, View rootView) { uiController.loopMainThreadUntilIdle(); long startTime = System.currentTimeMillis(); long endTime = startTime + timeout; do { // Iterate through all views on the screen and see if the view we are looking for is there already // for (View child : // TreeIterables.breadthFirstViewTraversal(rootView)) { // // found view with required ID // if (matchers.matches(child)) { // return true; // } // } if (test.test(rootView)) { return; } // Loops the main thread for a specified period of time. // Control may not return immediately, instead it'll return after the provided delay has passed and the queue is in an idle state again. uiController.loopMainThreadForAtLeast(100); } while (System.currentTimeMillis() < endTime); // in case of a timeout we throw an exception -> test fails throw new PerformException.Builder() .withCause(new TimeoutException()) .withActionDescription(getDescription()) .withViewDescription(HumanReadables.describe(rootView)) .build(); } }