آزمایش برنامه شما بخش ضروری از فرآیند توسعه Cast است. برنامه شما باید با دستورالعملهای Cast UX و چک لیست طراحی مطابقت داشته باشد تا اطمینان حاصل شود که کاربران تجربه Cast ثابتی دارند.
برای برنامههای اندروید، از چارچوبهای تست UI Automator و Espresso برای شبیهسازی تعاملات کاربر در برنامه خود و اجرای تستهای UI به صورت خودکار و تکرارپذیر استفاده کنید. برای کسب اطلاعات بیشتر در مورد تستهای UI خودکار، به بخش Automate user interface tests مراجعه کنید.
این راهنما نحوه اضافه کردن تستهای خودکار رابط کاربری به برنامه فرستنده اندروید شما را شرح میدهد.
محیط آزمایش را تنظیم کنید
اندروید استودیو برای ساخت و اجرای برنامه و تستهای شما توصیه میشود.
در دستگاه فیزیکی مورد استفاده برای آزمایش، در قسمت تنظیمات > گزینههای توسعهدهندگان ، انیمیشنهای سیستمی زیر را خاموش کنید:
- مقیاس انیمیشن پنجره
- مقیاس انیمیشن انتقال
- مقیاس مدت زمان انیماتور
نمونه فایل ساخت Gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 34
defaultConfig {
applicationId "com.example.package"
minSdkVersion 23
targetSdkVersion 34
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 را اضافه کنید
به طور پیشفرض، اندروید استودیو یک دایرکتوری کد منبع در src/androidTest/java/ برای قرار دادن تستهای instrumented و 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 را نشان میدهد:
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);
}
}