يعد اختبار تطبيقك جزءًا ضروريًا من عملية تطوير Google Cast. يجب أن يتوافق تطبيقك مع إرشادات تجربة المستخدم للبثّ وقائمة التحقق من التصميم لضمان توفير تجربة متسقة للمستخدمين.
بالنسبة إلى تطبيقات Android، يمكنك الاستفادة من أُطر عمل أداة برمجة واجهة المستخدم وEspresso لمحاكاة تفاعلات المستخدمين على تطبيقك وإجراء اختبارات واجهة المستخدم بطريقة مبرمَجة وقابلة للتكرار. لمزيد من المعلومات عن اختبارات واجهة المستخدم المبرمَجة، يُرجى الاطّلاع على مقالة تشغيل اختبارات واجهة المستخدم تلقائيًا.
يوضِّح هذا الدليل كيفية إضافة اختبارات واجهة المستخدم المبرمَجة إلى تطبيق المُرسِلين على Android.
إعداد بيئة الاختبار
ننصحك باستخدام استوديو Android لإنشاء تطبيقك وإجراء اختباراتك
على الجهاز الفعلي المستخدَم للاختبار، ضمن الإعدادات > خيارات المطوّرين، أوقف الصور المتحركة التالية للنظام:
- حجم الرسوم المتحركة للنافذة
- حجم الرسوم المتحركة للنقل
- طول مدة الرسوم المتحركة
مثال على ملف إنشاء 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'
}
إضافة أول اختبار لواجهة مستخدم Google Cast
يوفّر "استوديو Android" تلقائيًا دليل رمز مصدر على
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()));
}
}
اختبار اتصال البث
يوضّح هذا المثال كيفية محاكاة إجراءات المستخدم المتصلة بجهاز بث:
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);
}
}