تست‌های رابط کاربری فرستنده اندروید را خودکار کنید

آزمایش برنامه شما بخشی ضروری از فرآیند توسعه Cast است. برنامه شما باید با دستورالعمل‌های Cast UX و چک لیست طراحی مطابقت داشته باشد تا اطمینان حاصل شود که کاربران تجربه Cast مستمری دارند.

برای برنامه‌های اندروید، از چارچوب‌های تست UI Automator و Espresso برای شبیه‌سازی تعاملات کاربر در برنامه خود استفاده کنید و تست‌های UI خود را به روشی خودکار و تکرارپذیر اجرا کنید. برای کسب اطلاعات بیشتر در مورد تست‌های رابط کاربری خودکار، به تست‌های رابط کاربری خودکار مراجعه کنید.

این راهنما نحوه افزودن تست‌های خودکار رابط کاربری را به برنامه فرستنده Android خود توضیح می‌دهد.

محیط تست را تنظیم کنید

Android Studio برای ساخت و اجرای برنامه و آزمایشات شما توصیه می شود.

در دستگاه فیزیکی مورد استفاده برای آزمایش، در قسمت تنظیمات > گزینه‌های برنامه‌نویس ، انیمیشن‌های سیستمی زیر را خاموش کنید:

  • مقیاس انیمیشن پنجره
  • مقیاس انیمیشن انتقال
  • مقیاس مدت زمان انیماتور

نمونه فایل ساخت Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28

    defaultConfig {
        applicationId "com.example.package"
        minSdkVersion 21
        targetSdkVersion 28
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    ...

    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test:rules:1.1.1'
}

اولین آزمایش Cast UI را اضافه کنید

به طور پیش‌فرض، Android Studio یک فهرست کد منبع در src/androidTest/java/ برای قرار دادن تست‌های ابزاری و UI شما ارائه می‌کند. برای اطلاعات بیشتر، انواع تست و مکان را ببینید.

برای آزمایش اینکه آیا نماد Cast در برنامه نمایش داده می شود:

package com.example.package;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.mediarouter.app.MediaRouteButton;
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
import androidx.test.rule.ActivityTestRule;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;

@RunWith(AndroidJUnit4ClassRunner.class)
public class MyCastUITest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<>(MainActivity.class);

    @Test
    public void testCastButtonDisplay() throws InterruptedException {
        // wait for Cast button
        Thread.sleep(2000);

     onView(isAssignableFrom(MediaRouteButton.class)).check(matches(isDisplayed()));
    }
}

تست اتصال Cast

این مثال نحوه شبیه سازی اقدامات کاربر در اتصال به دستگاه Cast را نشان می دهد:

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;

import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.withId;

@RunWith(AndroidJUnit4ClassRunner.class)
public class MyCastUITest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<>(MainActivity.class);

    /**
     * Connecting to Cast device
     *  - Open Cast menu dialog when tapping the Cast icon
     *  - Select target Cast device and connect
     *  - Assert the Cast state is connected
     */
    @Test
    public void testConnectToCastDevice()
             throws InterruptedException, UiObjectNotFoundException {

        // wait for Cast button ready
        Thread.sleep(2000);

        // click on Cast icon and show a dialog
        onView(isAssignableFrom(MediaRouteButton.class))
                .perform(click());
        onView(withId(R.id.action_bar_root))
                .check(matches(isDisplayed()));

        // select target Cast device to connect
        UiDevice mDevice = UiDevice.getInstance(
                InstrumentationRegistry.getInstrumentation());
        mDevice.findObject(new UiSelector().text(TARGET_DEVICE)).click();

        // assert the Cast state is connected
        assertCastStateIsConnected(MAX_TIMEOUT_MS);
    }
}

جلسه Cast و وضعیت اتصال را می توان با اجرای یک تماس در رشته اصلی برنامه بازیابی کرد:

import android.content.Context;
import android.os.SystemClock;

import com.google.android.gms.cast.framework.CastContext;
import com.google.android.gms.cast.framework.CastSession;
import com.google.android.gms.cast.framework.SessionManager;

import static org.junit.Assert.assertTrue;

@RunWith(AndroidJUnit4ClassRunner.class)
public class MyCastUITest {
    private CastContext mCastContext;
    private CastSession mCastSession;
    private SessionManager mSessionManager;
    private boolean isCastConnected;

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<>(MainActivity.class);

    /**
     * Connecting to Cast device
     */
    @Test
    public void testConnectToCastDevice()
             throws InterruptedException, UiObjectNotFoundException {
        ......

        // assert the Cast state is connected
        assertCastStateIsConnected(MAX_TIMEOUT_MS);
    }

    /**
     * Check connection status from Cast session
     */
    private void assertCastStateIsConnected(long timeout)
              throws InterruptedException {

        long startTime = SystemClock.uptimeMillis();
        isCastConnected = false;

        while (!isCastConnected && SystemClock.uptimeMillis() - startTime < timeout) {

            Thread.sleep(500);

            // get cast instance and cast session from the app's main thread
            InstrumentationRegistry.getInstrumentation().runOnMainSync(
                    new Runnable() {
                        @Override
                        public void run() {
                            Context mTargetContext =
                                InstrumentationRegistry.getInstrumentation().getTargetContext();
                            mCastContext =
                                CastContext.getSharedInstance(mTargetContext);
                            mSessionManager = mCastContext.getSessionManager();
                            mCastSession =
                                mSessionManager.getCurrentCastSession();
                            isCastConnected = mCastSession.isConnected();
                        }
                    }
            );
        }

        assertTrue(isCastConnected);
    }
}