Kiểm thử ứng dụng là một phần cần thiết trong quá trình phát triển Cast. Ứng dụng của bạn phải tuân thủ Trải nghiệm người dùng của tính năng Truyền Nguyên tắc và Thiết kế Danh sách kiểm tra để đảm bảo người dùng có trải nghiệm Truyền nhất quán.
Đối với ứng dụng Android, hãy tận dụng Giao diện người dùng Automator và Kiểm thử Espresso để mô phỏng hoạt động tương tác của người dùng trên ứng dụng và chạy kiểm thử giao diện người dùng trong một một cách tự động và lặp lại. Để tìm hiểu thêm về các bài kiểm thử giao diện người dùng tự động, hãy xem Tự động hoá giao diện người dùng kiểm thử.
Hướng dẫn này mô tả cách thêm bài kiểm thử giao diện người dùng tự động vào ứng dụng dành cho người gửi Android.
Thiết lập môi trường kiểm thử
Bạn nên dùng Android Studio để tạo và chạy ứng dụng cũng như kiểm thử.
Trên thiết bị thực dùng để kiểm thử, trong phần Cài đặt > Tuỳ chọn cho nhà phát triển, hãy tắt các ảnh động hệ thống sau:
- Tỷ lệ hình động của cửa sổ
- Tỷ lệ hình động chuyển tiếp
- Tỷ lệ thời lượng của trình tạo hình động
Ví dụ về tệp bản dựng 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'
}
Thêm chương trình kiểm thử giao diện người dùng truyền đầu tiên
Theo mặc định, Android Studio cung cấp một thư mục mã nguồn tại
src/androidTest/java/
để đặt các kiểm thử đo lường và giao diện người dùng. Để biết thêm
thông tin, hãy xem Loại thử nghiệm và
vị trí.
Cách kiểm tra xem biểu tượng Truyền có hiển thị trên ứng dụng hay không:
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()));
}
}
Kiểm tra kết nối Cast
Ví dụ này cho thấy cách mô phỏng hành động của người dùng khi kết nối với thiết bị Truyền:
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);
}
}
Bạn có thể truy xuất phiên Truyền và trạng thái kết nối bằng cách thực hiện một lệnh gọi trên luồng chính của ứng dụng:
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);
}
}