27、自动化测试:Espresso for TV、UI Automator测试框架

说实话,做TV端开发最头疼的事是什么?我个人觉得是回归测试。

手机端你还能拿在手里点点点,TV端呢?得对着模拟器或者真机,用遥控器一个一个焦点移过去。测一遍下来,眼睛都快瞎了。我在做某视频平台TV版的时候,光是一个首页焦点遍历就要测20多种场景,手动测到吐。

所以,自动化测试在TV开发里不是「锦上添花」,而是「救命稻草」。今天我们就聊聊Android TV上最常用的两个测试框架:Espresso for TV 和 UI Automator。

为什么TV测试和手机测试不一样?

你想想看,手机测试的核心是「点击」和「滑动」。但TV呢?核心是「焦点移动」和「按键事件」。遥控器的方向键、OK键、返回键,这些才是TV交互的主旋律。

我在项目中遇到过一个问题:手机上的Espresso测试用例,直接搬到TV上跑,全挂。为什么?因为Espresso默认的onView操作是找View然后click(),但TV上你根本不需要click,你需要的是按遥控器方向键让焦点移动到目标上,再按OK键。

嗯,这里要注意:TV自动化测试的本质,是模拟遥控器操作,而不是模拟触摸点击。

Espresso for TV:专为遥控器而生

Google官方其实提供了Espresso的TV扩展库。说白了,就是把原来的click()换成了按键模拟。

核心依赖:

androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
// TV扩展
androidTestImplementation 'androidx.test.espresso:espresso-remote:3.5.1'

我个人习惯用 onView() 配合 perform() 来模拟按键。比如这样:

@Test
public void testFocusMoveToSearchButton() {
    // 先找到搜索按钮
    onView(withId(R.id.btn_search))
        .perform(ViewActions.pressKey(KeyEvent.KEYCODE_DPAD_DOWN));
    
    // 检查焦点是否移动到了搜索按钮
    onView(withId(R.id.btn_search))
        .check(matches(isFocused()));
}

这段代码看起来简单,但坑不少。我曾经踩过一个坑:pressKey() 是按一次方向键,但如果目标控件在列表深处,你得按很多次。怎么办?

我的经验:写一个循环按压的辅助方法:

public static void pressKeyMultipleTimes(int keyCode, int times) {
    for (int i = 0; i < times; i++) {
        onView(withId(android.R.id.content))
            .perform(ViewActions.pressKey(keyCode));
    }
}

这样调用起来就清爽多了:pressKeyMultipleTimes(KEYCODE_DPAD_DOWN, 5);

UI Automator:跨应用测试的利器

Espresso 有个限制:它只能测试你当前应用内的界面。但TV上经常需要跨应用测试,比如从你的App跳转到系统设置,或者调用第三方播放器。

这时候就得用 UI Automator 了。它能操作整个设备,包括系统UI。

核心依赖:

androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'

UI Automator 的用法和 Espresso 不太一样。它通过 UiDevice 来操作设备,通过 UiSelector 来查找控件。

@Test
public void testOpenSystemSettings() throws Exception {
    // 获取设备实例
    UiDevice device = UiDevice.getInstance(getInstrumentation());
    
    // 按Home键回到桌面
    device.pressHome();
    
    // 打开系统设置(假设桌面有设置图标)
    UiObject settingsApp = device.findObject(
        new UiSelector().text("设置")
    );
    settingsApp.clickAndWaitForNewWindow();
    
    // 验证设置界面打开了
    UiObject wifiOption = device.findObject(
        new UiSelector().text("Wi-Fi")
    );
    assertTrue(wifiOption.exists());
}

这里有个关键点:clickAndWaitForNewWindow()click() 的区别。前者会等待新窗口加载完成,后者只管点。在TV上,我建议一律用 clickAndWaitForNewWindow(),因为TV的界面切换往往有动画,不等的话后续操作容易失败。

Espresso vs UI Automator:怎么选?

很多新手会纠结这个问题。我直接给结论:

场景 推荐框架 原因
测试自己App内的UI Espresso for TV 速度快,API简洁,支持IdlingResource等待
测试跨应用流程 UI Automator 能操作系统UI和其他App
测试焦点遍历顺序 Espresso for TV 可以精确断言某个View是否获得焦点
测试遥控器按键组合 两者皆可 UI Automator的按键模拟更丰富

我个人习惯是:单元测试和UI组件测试用Espresso,端到端场景测试用UI Automator。两者互补,不冲突。

TV自动化测试的避坑指南

做TV自动化测试,有几个坑我几乎每次都会遇到。分享出来,你们少走弯路。

我曾经踩过的坑:

  • 焦点不在预期位置:TV的焦点状态受很多因素影响,比如上一个测试用例的残留状态。解决方案:每个测试用例开始前,先按Home键重置焦点。
  • 动画导致等待超时:TV的转场动画通常比手机长。我建议把默认超时时间从5秒改成10秒:@Test(timeout = 10000)
  • RecyclerView滚动问题:TV上的列表通常用Leanback的VerticalGridView。用Espresso滚动它时,别用scrollTo(),用方向键模拟滚动更可靠。

实战:写一个完整的TV测试用例

我们来看一个实际例子。假设我们要测试一个TV视频App的首页:焦点默认在第一个视频卡片上,按方向键下可以移动到第二行,按OK键进入详情页。

@RunWith(AndroidJUnit4.class)
public class HomePageTest {

    @Rule
    public ActivityTestRule activityRule = 
        new ActivityTestRule<>(MainActivity.class);

    @Test
    public void testFocusAndNavigation() {
        // 1. 验证默认焦点在第一个视频卡片
        onView(withId(R.id.video_card_0))
            .check(matches(isFocused()));

        // 2. 按方向键下,焦点移到第二行第一个
        onView(withId(R.id.video_card_0))
            .perform(ViewActions.pressKey(KeyEvent.KEYCODE_DPAD_DOWN));
        onView(withId(R.id.video_card_1))
            .check(matches(isFocused()));

        // 3. 按OK键进入详情页
        onView(withId(R.id.video_card_1))
            .perform(ViewActions.pressKey(KeyEvent.KEYCODE_DPAD_CENTER));

        // 4. 验证详情页打开了
        onView(withId(R.id.detail_title))
            .check(matches(isDisplayed()));
    }
}

这个用例看起来简单,但覆盖了TV测试的三个核心点:焦点验证、方向键导航、确认键触发。你想想看,如果手动测这个流程,每个方向键都要按一次,20个卡片就得按20次。自动化测试一次跑完,省心省力。

SVG:TV自动化测试知识体系

下面这张图总结了本章的核心内容,方便你快速回顾:

TV自动化测试知识体系 Espresso for TV UI Automator 核心特性 • 模拟遥控器按键(pressKey) • 焦点状态断言(isFocused) • 支持IdlingResource等待 核心特性 • 跨应用操作(系统UI) • UiDevice + UiSelector • 支持按键组合模拟 适用场景:单元测试用Espresso,端到端用UI Automator 避坑:重置焦点 → 延长超时 → 用方向键模拟滚动

总结

TV自动化测试,说白了就是让机器帮你按遥控器。Espresso for TV 适合精细的焦点验证,UI Automator 适合跨应用的大场景。两者结合,基本能覆盖TV开发中90%的测试需求。

我建议你从今天开始,把最常用的几个操作流程写成自动化用例。比如首页加载、焦点遍历、播放器启动。刚开始可能觉得麻烦,但跑上几次你就知道有多香了。

一个小技巧:在CI/CD流水线里,把TV自动化测试放在夜间构建中。白天改代码,晚上自动跑测试,第二天早上看报告。这样既不影响开发效率,又能保证质量。


公众号:蓝海资料掘金营,微信deep3321