资讯专栏INFORMATION COLUMN

Android自动化测试-从入门到入门(3)Espresso入门

Songlcy / 2243人阅读

摘要:附录自动化测试从入门到入门自动化测试从入门到入门自动化测试从入门到入门入门自动化测试从入门到入门自动化测试从入门到入门的测试自动化测试从入门到入门会玩的自动化测试从入门到入门

根据该系列之前的两篇文章:Hello Testing和Testing APIs,我们已经对Android自动化测试的整体背景有了一些了解。还记得第一篇文章里我提到过的基本思路么?

把自己当成用户,只关注我能看到的东西。

这个思路的意思是在于,我要让机器模拟我的测试过程,那么我就需要针对那些我(作为用户)能看到的东西,也就是UI。比如说,我并不关心某个网络请求返回值的具体数据是否正确,我关心的是我能在UI上看到我希望看到的结果。基于此,我做各个测试用例的一个通用的思路就是:

找到某个元素,做一些操作,检查结果。

这里包含了三个流程:

找元素:找到UI上测试所针对的元素;

做操作:给这个元素做一些操作;

检查结果:这个元素做出了我期望的行为。

再直观一点,我向一个表单输入一段文字,那么整个过程就可以描述为:

找元素:找到EditText;

做操作:向EditText输入字符串;

检查结果:EditText显示了我输入的字符串。

以上三个小步骤实际上也是我作为用户在使用一个APP的时候所遵循的流程。而我们的测试也是基本遵循这样一个流程的。

Espresso

为了实现我们的自动化测试流程,我们采用Espresso进行脚本的编写。我们需要在build.gradledependencies中增加如下依赖:

androidTestCompile "com.android.support.test.espresso:espresso-core:2.2.1"

请注意,在这里我并没有完整地将build.gradle贴出来,只是贴出来了需要增加的部分。这也就意味着,在第一篇Hello Testing中提到的那些配置也都是必不可少的。

另外,我们还需要一个叫做hamcrest的库,用来和Espresso配合使用,因此在build.gradle中添加:

androidTestCompile "org.hamcrest:hamcrest-library:1.3"
建一个Test Case

还记得之前文章中我们提到的那个AppStartActivityTest Case么?我们可以在相应的目录下建立我们自己的Test Case了!这里贴一下Espresso官方提供的一个example:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class HelloWorldEspressoTest {

    @Rule
    public ActivityTestRule mActivityRule = new ActivityTestRule(MainActivity.class);

    @Test
    public void listGoesOverTheFold() {
        onView(withText("Hello world!")).check(matches(isDisplayed()));
    }
}

要运行我们的测试用例,我们可以参照第一篇文章中采用Android Studio的方法,也可以在终端中切换到当前项目的路径下,执行如下命令:

./gradlew cAT

其中,cAT意为connectedAndroidTest

找元素

我们现在需要找页面中对应的元素了!Espresso提供了一个onView()方法用来寻找UI上指定的元素,该方法定义如下:

public static ViewInteraction onView(final Matcher viewMatcher) {}

这个方法接收一个Matcher类型的入参,返回一个ViewInteraction对象,其所做的事情就是根据Matcher所指定的条件,在当前UI页面上寻找符合条件的View,并且把相应的View返回出来。这样说还是比较抽象,我们可以用一个具体的例子加以说明。

当我们在实现布局的时候,每个控件都会有一些特殊的属性来确定其唯一性,比如最常用的R.idMatcher支持通过控件的唯一ID来从当前页面上寻找目标控件,对应的方法为withId(),该方法定义如下:

public static Matcher withId(final int id) {}

大家可以看到,该方法接收了一个int类型的入参,返回了一个Matcher对象,于是,采用如下写法:

onView(withId(id));

我们就能在当前页面找到指定ID所对应的目标控件了。

再描述一遍这个流程以便更清晰:我现在要找一个R.id为指定id的控件,那么我就从我的这个id出发,先生成一个查找匹配条件:withId(id)。然后把这个条件传给onView()方法:onView(withId(id)),让onView()方法根据这个条件找到我们想要的那个控件!实际上这行代码也是很符合我们的正常思维,可以读作:

Find a view with Id of the specific id.

实际上,Espresso提供了很多方法来让我们自定义我们的查找条件。比如我们可以通过withText()方法来寻找显示了指定文案的控件等等。具体支持的Matcher类型可以参考Espresso cheat sheet。

需要提醒大家一点的是,onView()方法在根据匹配条件进行查找时,它的目标是找到唯一的一个目标控件。如果我们制定的匹配条件有多个控件可以匹配(比如复用了layout的布局,或者显示相同文字的TextView等),该方法会抛出一个AmbiguousViewMatcherException异常,因此我们在构造匹配条件时,一定要确保能查找到的目标控件是唯一的。如果单一的匹配条件无法精确地匹配出来唯一的控件,我们可能还需要额外的匹配条件,此时可以用allOf()方法来进行复合匹配条件的构造:

onView(allOf(withId(id), withText(text)))

以上代码可以查找IDid同时显示的文字内容为text的控件。这里需要注意的是,为了保证自动化测试的效率,我们应尽可能减少匹配条件的数量。如果用一个匹配条件能够满足我们的需求,我们也就没有必要再用allOf()来构造复合匹配条件了。

操作元素

找到了目标元素,接下来我们该针对该元素做一些操作了!
Espresso提供了如下方法来对相应的元素做操作:

public ViewInteraction perform(final ViewAction... viewActions) {}

该方法定义在ViewInteraction类里面。还记得onView()方法的返回值么?yes,正是一个ViewInteraction对象。因此,我们可以在onView()方法找到的元素上直接调用perform()方法进行一系列操作:

onView(withId(id)).perform(click())

如上代码对onView()查询到的元素做了一次点击的操作。请注意,perform()方法的入参是变长参数,也就意味着,我们可以依次对某个元素做多个操作:

onView(withId(id)).perform(click(), replaceText(text), closeSoftKeyboard())

以上代码对目标元素依次做了点击、输入文本、关闭输入法键盘的操作。这是一个典型的填写表单的行为。

检查结果

到目前为止,我们已经能找到元素,也能够对元素进行一些操作了!接下来我们需要检查一下这些操作的结果是否符合我们的预期。

Espresso提供了一个check()方法用来检测结果:

public ViewInteraction check(final ViewAssertion viewAssert) {}

该方法接收了一个ViewAssertion的入参,该入参的作用就是检查结果是否符合我们的预期。一般来说,我们可以调用如下的方法来自定义一个ViewAssertion

public static ViewAssertion matches(final Matcher viewMatcher) {}

这个方法接收了一个匹配规则,然后根据这个规则为我们生成了一个ViewAssertion对象!还记得Matcher这个类型么!!是的,这就是onView()方法的入参!实际上他们是同一个类型,其使用方法也是完全一致的。

比如,我想检查一下指定idTextView是否按照我的预期显示了一段text文本,那么我就可以这样写:

onView(withId(id)).check(matches(withText(text)))

简洁明了。ViewAssertion的支持也可以参照这个Espresso cheat sheet。

恭喜入门!

到目前为止,我们已经使用Espresso完成了一个小的测试流程。如果你都看懂了,那么恭喜你,你已经成功入门,可以写一些简单的Test Case了!

那么回过头来,我们就可以理解本文开头贴出来的Espresso官网提供的那个小案例了。在listGoesOverTheFold()方法中,只执行了一行代码:

onView(withText("Hello world!")).check(matches(isDisplayed()));

其意义也已经足够明晰:检查"Hello world!"是否成功地显示在了屏幕上。

附录

Android自动化测试-从入门到入门(1) Hello Testing!
Android自动化测试-从入门到入门(2) Testing APIs
Android自动化测试-从入门到入门(3) Espresso入门
Android自动化测试-从入门到入门(4) uiautomatorviewer
Android自动化测试-从入门到入门(5) AdapterView的测试
Android自动化测试-从入门到入门(6) 会玩的Espresso
Android自动化测试-从入门到入门(7) UI Automator

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65408.html

相关文章

  • Android动化测试-入门入门(6)会玩的Espresso

    摘要:附录自动化测试从入门到入门自动化测试从入门到入门自动化测试从入门到入门入门自动化测试从入门到入门自动化测试从入门到入门的测试自动化测试从入门到入门会玩的自动化测试从入门到入门 之前的文章中,我们介绍了Android自动化测试的一些背景,以及Espresso的基本应用。除了之前介绍过的Espresso的相关用法,Espresso还提供了一些其他的用法,可以让我们在不同场景下灵活使用。这篇...

    Aklman 评论0 收藏0
  • Android动化测试-入门入门(4)uiautomatorviewer

    摘要:右下角部分显示当前选中控件的各个属性。然后,向这个中输入账号信息就完成了一个表单的输入。我们可以根据属性区域显示的来进行匹配账号小总结所提供的界面简单,使用方便,对于我们的自动化测试来说是一个很好的辅助工具。 我们用如下一行代码来回顾一下之前介绍过的内容: import static android.support.test.espresso.Espresso.onView; impo...

    winterdawn 评论0 收藏0
  • Android动化测试-入门入门(7)UI Automator

    摘要:检查操作的结果是否符合预期。大家在实际编写自动化测试脚本时可以灵活选用。 到目前为止,我们已经完成了对Espresso的介绍。从之前的文章我们可以看到,Espresso对Android APP的自动化测试提供了一系列非常强大的工具和方法。 现在试想这样一个场景:我们在APP中有一个更改头像的功能,此时我们需要调用系统相机进行拍照,然后再回到APP提交拍好的照片。在这种场景下,我们需要从...

    Dean 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<