Android Gönderen Kullanıcı Arayüzü Testlerini Otomatikleştirme

Uygulamanızı test etmek, Cast geliştirme sürecinin gerekli bir parçasıdır. Uygulamanız, kullanıcılara tutarlı bir Cast deneyimi sunmak için Yayın Kullanıcı Deneyimi Yönergeleri'ne ve Tasarım Kontrol Listesi'ne uygun olmalıdır.

Android uygulamalarında, uygulamanızdaki kullanıcı etkileşimlerini simüle etmek ve kullanıcı arayüzü testlerinizi otomatik ve tekrarlanabilir bir şekilde çalıştırmak için UI Automator ve Espresso test çerçevelerinden yararlanın. Otomatik kullanıcı arayüzü testleri hakkında daha fazla bilgi için Kullanıcı arayüzü testlerini otomatikleştirme bölümüne bakın.

Bu kılavuzda, Android gönderen uygulamanıza otomatik kullanıcı arayüzü testlerini nasıl ekleyeceğiniz açıklanmaktadır.

Test ortamını ayarlama

Uygulama ve testlerinizi oluşturup çalıştırmak için Android Studio önerilir.

Test için kullanılan fiziksel cihazda, Ayarlar > Geliştirici seçenekleri altında aşağıdaki sistem animasyonlarını kapatın:

  • Pencere animasyonu ölçeği
  • Geçiş animasyonu ölçeği
  • Animatör süre ölçeği

Örnek Gradle derleme dosyası

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'
}

İlk Cast kullanıcı arayüzü testini ekleme

Android Studio, donatılmış ve kullanıcı arayüzü testlerinizi yerleştirmek için src/androidTest/java/ adresinde varsayılan olarak bir kaynak kodu dizini sağlar. Daha fazla bilgi edinmek için Test türleri ve konum bölümünü inceleyin.

Uygulamada bir Google Cast simgesinin görüntülenip görüntülenmediğini test etmek için:

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 bağlantısını test et

Bu örnekte, bir Yayın cihazına bağlanırken kullanıcı işlemlerinin nasıl simüle edileceği gösterilmektedir:

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

Yayınlama oturumu ve bağlantı durumu, uygulamanın ana iş parçacığından bir çağrı yürütülerek alınabilir:

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