返回

Espresso对Android View的定位原理剖析

Android

前言

Android Espresso是谷歌官方推出的用于Android UI测试的框架,它可以模拟用户操作,对UI控件进行点击、输入、滚动等操作,并对测试结果进行断言。Espresso定位View的方式有多种,包括使用资源ID、使用View的文本内容、使用View的符等。本文将从Android Espresso如何定位View的角度,深入分析View的定位原理。

Espresso如何定位View

Espresso定位View的方式有多种,包括使用资源ID、使用View的文本内容、使用View的符等。其中,使用资源ID是定位View最直接的方式,也是Espresso最常用的定位方式。

当使用资源ID定位View时,Espresso会先通过View的资源ID找到View在Activity中的位置,然后通过View的位置来找到View本身。如果View的资源ID不唯一,则Espresso会抛出异常。

源码分析

为了更好地理解Espresso的定位原理,我们来看一下Espresso的源码。Espresso的定位逻辑主要集中在com.google.android.espresso.ViewInteraction类中。ViewInteraction类提供了多种定位View的方法,包括withId()withText()withContentDescription()等。

withId()方法为例,withId()方法的实现如下:

public static ViewInteraction withId(int id) {
    return new WithIdViewInteraction(id);
}

withId()方法接受一个资源ID作为参数,并返回一个新的WithIdViewInteraction对象。WithIdViewInteraction类是ViewInteraction类的子类,它提供了更详细的定位逻辑。

WithIdViewInteraction类的构造函数中,会首先调用ViewInteraction类的构造函数,然后将资源ID存储到WithIdViewInteraction类的成员变量中。

public WithIdViewInteraction(int id) {
    super();
    this.id = id;
}

当调用WithIdViewInteraction类的perform()方法时,会首先调用ViewInteraction类的perform()方法。ViewInteraction类的perform()方法会将当前ViewInteraction对象传递给ViewAction对象,然后由ViewAction对象执行具体的定位逻辑。

WithIdViewInteraction类的perform()方法中,会首先通过资源ID找到View在Activity中的位置,然后通过View的位置来找到View本身。如果View的资源ID不唯一,则会抛出异常。

@Override
public void perform(UiController uiController, ViewInteractionStub viewInteractionStub) {
    View view = viewInteractionStub.getView();
    if (view == null) {
        throw new PerformException.Builder()
                .withActionDescription(this.getDescription())
                .withViewDescription(viewInteractionStub.getViewDescription())
                .withCause(new RuntimeException("Could not find a view with id: " + id))
                .build();
    }
    perform(uiController, view);
}

总结

通过对Espresso源码的分析,我们了解了Espresso定位View的原理。Espresso通过使用资源ID、View的文本内容、View的描述符等方式来定位View。在定位View时,Espresso会首先通过资源ID找到View在Activity中的位置,然后通过View的位置来找到View本身。如果View的资源ID不唯一,则Espresso会抛出异常。