Espresso学习笔记--google doc前四篇部分翻译和理解

那么针对Espresso这个框架google提供了下面几篇文章:
Espresso学习笔记--google doc前四篇部分翻译和理解_第1张图片
本文包含前4篇的部分翻译和个人理解,后面两篇作为提高吧,笔者还没来得及看

00 01入门

谷歌建议我们做自动化的时候关闭动画
然后在build.gradle里面增加testrunner和依赖库
在· android.defaultConfig:里面添加,

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

以及添加依赖:

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'androidTestCompile 'com.android.support.test:runner:0.5'

PS:配置上述依赖库如果报错,需要加入

configurations.all {
    resolutionStrategy.force 'com.android.support:support-annotations:23.1.0'
}

(笔者提醒,各个依赖包作用参照上一篇文章)
另外呢,使用espresso系统会自动收集信息,可以选择关掉。

02基础

espresso没有直接提供类似getView和getCurrentActivity这样的方法直接获取控件,这是因为保护控件以及在UI线程之外操作(这话有点看不懂)。
然后介绍几个主要的类:
Espresso:主入口函数了
ViewMatchers:通过一个或者多个来定位层级里面的控件,是一个匹配的合集
ViewActions:动作合集
ViewAssertions:assert嘛,应该都知道的

下面就开始分别介绍了

定位
首先是onView这个api
espresso使用了hamcrest matchers这个匹配库来匹配的,就是比junit的assert更加强大的意思了。然后最好使用R。id来定位控件,但是有的控件却没有id或共用很多个id(经常遇到,悲剧),所以你需要访问私有的activity或者fragment找到这个view(其实就是访问组件的私有方法暴露自己的意思)或者通过已知的R.id父容器然后慢慢定位到这个控件(找上一级容器控件确实用的比较多),所以espresso允许你用ViewMatcher和你自己的方法去找控件。
有的时候R.id匹配多个控件,就会报AmbiguousViewMatcherException这个异常
你可以看这个异常找到你需要的定位信息(就是说这个异常包含相同R.id的不同特性,你使用这些信息去定位就行了)
定位的时候,espresso支持not,比如

onView(allOf(withId(R.id.my_view), not(withText("Unwanted"))))

最后面,谷歌说了,一个好的应用是应该包含有descriptive text or have a content description就是描述字段的,如果没有请作为BUG添加上去(谷歌真幽默,开发才不会理你!)

动作
动作其实包含很多,比如click、typeText、scrollTo,同时一个perform里面可以包含一个或者多个action
onView(…).perform(typeText(“Hello”), click());
这里注意的是scrollTo在视图完全显示出来的时候并不生效比如大屏,大分辨率。

断言
espresso使用check()方法来进行断言的。最常用的是matches()方法,它断言的是当前选择的view的状态。
如果想验证text为hello的view,可以这样
check(matches(withText(“Hello!”)));
最后要注意这两者的差异,view没有显示出来以及view不在view层级里面(其实就是view.invisible或者gone这种情况和根本没有加载到控件树这种情况)

AdapterView的使用
使用onData。
AdapterView是一个特殊的装载的内容不断变化的适配器。
AdapterView装载的子集view,并不能全部展示在当前加载的页面上,onView并不能找到不加载到当前页面的view(嗯,普及下原理,找控件其实是一次性dump下来层级的,然后遍历返回,adapterview因为很长,所以当前屏幕只能加载其一部分,所以没办法点击到看不见的地方,层级工具也可以体现)。
espresso为了解决这个问题,提供了onData()这个方法,在你操作view之前就把adapter的item装载进来,并设置焦点,这样就能操作adapterview里面的控件了。
然而,自定义AdapterView可能会有问题(哎哟我去),比如不规范的继承,尤其是getItem方法,那就不适用了,只能重构你的代码了,参考AdapterViewProtocal协议构建(貌似自己写一个onData方法也可以吧,需要弄懂原理先,开发不保证理你啊)。
使用的时候就是用onData替代普通的onView
下面是一个onData的例子,是一个spinner,有多个饮料名字,点击某个item会把名字显示在TextView上面。
需要测试的是 点击–选择item–查看TextView。
1.onView(withId(R.id.spinner_simple)).perform(click());
2.onData(allOf(is(instanceOf(String.class)), is(“Americano”))).perform(click());
3.onView(withId(R.id.spinnertext_simple))
.check(matches(withText(containsString(“Americano”))));

其他
Espresso提供日志供我们查看。

两个异常
通过onView找不到会爆异常:NoMatchingViewException,这时候会打印层级信息,你可以查看哪个才是匹配的。
onView找不到的时候可以试试onData()查找。

03.提供了一个api图

神奇的图,down到桌面当成api索引用,谷歌感谢了 哈哈
Espresso学习笔记--google doc前四篇部分翻译和理解_第2张图片

04.Espresso提供的Intent

这是espresso的扩展功能,允许你在测试的时候发送android的intent,类似mocktis。
所以为了使用,你要在配置文件加入:

androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'

这个插件要求高版本的,所以:

androidTestCompile 'com.android.support.test:runner:0.5'androidTestCompile 'com.android.support.test:rules:0.5'androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

使用IntentTestRule替代ActivityTestRule,会在@Test前初始化,会在每个用例跑完之后释放。activity将会在每一个用例之后finish掉,这个规则同样用于ActivityTestRule(吐槽,前面没有提到activitytestrule,这里才说,这是扩展篇啊,这是谷歌笔误吗)。
Espresso-intent记录了所有启动应用activity的意图,比方说启动:
intended(toPackage(“com.android.phone”));}
使用这类api,你还可以模拟startActivityForResult 获得返回值,当我们没办法获得用户接口以及返回值这回特别有用,类似与 Mockito.when
例子:

@Testpublic void activityResult_IsHandledProperly() {
    // Build a result to return when a particular activity is launched.
    Intent resultData = new Intent();
    String phoneNumber = "123-345-6789";
    resultData.putExtra("phone", phoneNumber);
    ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData);

    // Set up result stubbing when an intent sent to "contacts" is seen.
    intending(toPackage("com.android.contacts")).respondWith(result));

    // User action that results in "contacts" activity being launched.
    // Launching activity expects phoneNumber to be returned and displays it on the screen.
    onView(withId(R.id.pickButton)).perform(click());

    // Assert that data we set up above is shown.
    onView(withId(R.id.phoneNumber).check(matches(withText(phoneNumber)));}

这个例子是点击某个按钮,从系统的通讯录得到一个号码,然后返回来。如此,就是提供了mock activityresult的方法。
最后,intended还提供了自定义启动方法。

intended(allOf(
    hasAction(equalTo(Intent.ACTION_VIEW)),
    hasCategories(hasItem(equalTo(Intent.CATEGORY_BROWSABLE))),
    hasData(hasHost(equalTo("www.google.com"))),
    hasExtras(allOf(
        hasEntry(equalTo("key1"), equalTo("value1")),
        hasEntry(equalTo("key2"), equalTo("value2")))),
        toPackage("com.android.browser")));

(这个知道就行了,没想到怎么用,也没觉得多大用)

05.06

笔者还没看

你可能感兴趣的:(自动化测试)