根据该系列以前的两篇文章:Hello Testing和Testing APIs,咱们已经对Android自动化测试的总体背景有了一些了解。还记得第一篇文章里我提到过的基本思路么?html
把本身当成用户,只关注我能看到的东西。
这个思路的意思是在于,我要让机器模拟个人测试过程,那么我就须要针对那些我(做为用户)能看到的东西,也就是UI。好比说,我并不关心某个网络请求返回值的具体数据是否正确,我关心的是我能在UI上看到我但愿看到的结果。基于此,我作各个测试用例的一个通用的思路就是:android
找到某个元素,作一些操做,检查结果。
这里包含了三个流程:git
找元素
:找到UI上测试所针对的元素;github
作操做
:给这个元素作一些操做;segmentfault
检查结果
:这个元素作出了我指望的行为。网络
再直观一点,我向一个表单输入一段文字,那么整个过程就能够描述为:布局
找元素
:找到EditText;测试
作操做
:向EditText输入字符串;gradle
检查结果
:EditText显示了我输入的字符串。ui
以上三个小步骤实际上也是我做为用户在使用一个APP的时候所遵循的流程。而咱们的测试也是基本遵循这样一个流程的。
为了实现咱们的自动化测试流程,咱们采用Espresso
进行脚本的编写。咱们须要在build.gradle
的dependencies
中增长以下依赖:
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'
还记得以前文章中咱们提到的那个AppStartActivity
的Test Case
么?咱们能够在相应的目录下创建咱们本身的Test Case
了!这里贴一下Espresso
官方提供的一个example:
@RunWith(AndroidJUnit4.class) @LargeTest public class HelloWorldEspressoTest { @Rule public ActivityTestRule<MainActivity> 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<View> viewMatcher) {}
这个方法接收一个Matcher<View>
类型的入参,返回一个ViewInteraction
对象,其所作的事情就是根据Matcher<View>
所指定的条件,在当前UI页面上寻找符合条件的View
,而且把相应的View
返回出来。这样说仍是比较抽象,咱们能够用一个具体的例子加以说明。
当咱们在实现布局的时候,每一个控件都会有一些特殊的属性来肯定其惟一性,好比最经常使用的R.id
。Matcher<View>
支持经过控件的惟一ID来从当前页面上寻找目标控件,对应的方法为withId()
,该方法定义以下:
public static Matcher<View> withId(final int id) {}
你们能够看到,该方法接收了一个int
类型的入参,返回了一个Matcher<View>
对象,因而,采用以下写法:
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)))
以上代码能够查找ID
为id
同时显示的文字内容为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<? super View> viewMatcher) {}
这个方法接收了一个匹配规则,而后根据这个规则为咱们生成了一个ViewAssertion
对象!还记得Matcher
这个类型么!!是的,这就是onView()
方法的入参!实际上他们是同一个类型,其使用方法也是彻底一致的。
好比,我想检查一下指定id
的TextView
是否按照个人预期显示了一段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