خودکارسازی آزمایش‌های میانای کاربر فرستنده Android

آزمایش برنامه شما بخش ضروری از فرایند توسعه Cast است. برنامه شما باید از رهنمودهای تجربه کاربری Cast و فهرست وارسی طراحی پیروی کند تا مطمئن شوید کاربران تجربه یکسانی از Cast دارند.

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

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

راه‌اندازی محیط آزمایش

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

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

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

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

apply plugin: 'com.android.application'

android {
    compileSdkVersion 35

    defaultConfig {
        applicationId "com.example.package"
        minSdkVersion 24
        targetSdkVersion 35
        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/ برای قرار دادن تست‌های ابزاری و میانای کاربر شما ارائه می‌دهد. برای اطلاعات بیشتر، انواع آزمایش و مکان را ببینید.

برای آزمایش اینکه نماد «پخش محتوا» در برنامه نمایش داده می‌شود یا نه:

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 شبیه‌سازی کنید:

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);
    }
}

وضعیت اتصال و جلسه «پخش محتوا» را می‌توان با اجرای تماس در رشته اصلی برنامه بازیابی کرد:

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);
    }
}