安卓 espresso 测试流程, 案例

原创
2022/08/25 09:21
阅读数 200

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();
        }
    }
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部