技术文档:官方地址
https://code.google.com/p/android-test-kit/wiki/Espresso
https://google.github.io/android-testing-support-library/docs/espresso/advanced/index.html
参考文档:
http://www.jianshu.com/p/03118c11c199
http://www.vogella.com/tutorials/AndroidTestingEspresso/article.html
简单的android ui自动化测试
优点:可以实现ui的自动化测试;
进行简单的mock数据测试,不强依赖于业务&&服务端;
容易实现;
1.使用方法
a.在defaultConfig内增加,testInstrumentationRunner来运行脚本
testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"
b.依赖Espresso测试框架
androidTestCompile('com.android.support.test:runner:0.2')
androidTestCompile'com.android.support.test:rules:0.2'
androidTestCompile'com.android.support.test.espresso:espresso-core:2.1'
androidTestCompile'com.android.support.test.espresso:espresso-intents:2.2.2'
注意:若依赖引入时报错,某些框架的版本太低,根据错误进行包的引入即可。Eg。
androidTestCompile'com.android.support:support-annotations:23.1.1'
androidTestCompile'com.google.code.findbugs:jsr305:3.0.0'
c.编写测试代码
文件可编写在:androidTest文件夹下,根据待测页面的路径&名称进行命名。
Import框架:
importandroid.app.Activity;
importandroid.app.Instrumentation;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.support.test.InstrumentationRegistry;
importandroid.support.test.rule.ActivityTestRule;
importandroid.support.test.runner.AndroidJUnit4;
importandroid.test.suitebuilder.annotation.LargeTest;
importcom.ali.spark.R;
importcom.ali.spark.biz.publish.tag.EditTagModel;
importcom.ali.spark.biz.tagsearch.TagChooseActivity;
importcom.ali.spark.pojo.vo.tag.BaseTagVO;
importcom.ali.spark.pojo.vo.tag.CommonTagVO;
importcom.ali.spark.pojo.vo.tag.CurrencyTagVO;
importcom.ali.spark.pojo.vo.tag.TagExtVO;
importorg.junit.Rule;
importorg.junit.Test;
importorg.junit.runner.RunWith;
importjava.util.ArrayList;
importjava.util.List;
import staticandroid.support.test.espresso.Espresso.onData;
import staticandroid.support.test.espresso.Espresso.onView;
import staticandroid.support.test.espresso.Espresso.pressBack;
import staticandroid.support.test.espresso.action.ViewActions.click;
import staticandroid.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import staticandroid.support.test.espresso.action.ViewActions.swipeUp;
import staticandroid.support.test.espresso.action.ViewActions.typeText;
import staticandroid.support.test.espresso.assertion.ViewAssertions.matches;
import staticandroid.support.test.espresso.intent.Intents.intending;
import staticandroid.support.test.espresso.intent.matcher.IntentMatchers.toPackage;
import staticandroid.support.test.espresso.matcher.RootMatchers.withDecorView;
import staticandroid.support.test.espresso.matcher.ViewMatchers.hasSibling;
import staticandroid.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import staticandroid.support.test.espresso.matcher.ViewMatchers.withId;
import staticandroid.support.test.espresso.matcher.ViewMatchers.withText;
import staticorg.hamcrest.Matchers.allOf;
import staticorg.hamcrest.Matchers.not;
import staticorg.hamcrest.CoreMatchers.containsString;
import staticorg.hamcrest.CoreMatchers.is;
import staticorg.hamcrest.CoreMatchers.startsWith;
import staticorg.hamcrest.Matchers.hasToString;
@RunWith(AndroidJUnit4.class)
@LargeTest
public classTagChooseActivityInstrumentationTest{
private static finalStringSTRING_TO_BE_TYPED="123";
//要测试的页面activity
@Rule
publicActivityTestRulemActivityRule=newActivityTestRule<>(
TagChooseActivity.class,true,false);
/*币种的选择
listview可以使用wityText来判定是哪一个控件
*/@Test
public voidchoosePrice() {
// launchActivity的模式,可以mock不同的intents检验页面的展示情况
Context targetContext =InstrumentationRegistry.getInstrumentation().getTargetContext();
Intent intent =newIntent(targetContext, TagChooseActivity.class);
mActivityRule.launchActivity(intent);
String priceType ="美元";
//寻找控件
onView(withId(R.id.price_type)).perform(click());
//操作控件
onView(withText(priceType)).perform(click());
//检查结果
onView(withId(R.id.price_type)).check(matches(withText(priceType)));
}
d.运行
右键运行:
运行结果:
2.功能实现
a.唤起页面&&初始化intent
//ActivityTestRule设置activity launch的模式,也可以不设置,则直接唤起activity
publicActivityTestRulemActivityRule=newActivityTestRule<>(
TagChooseActivity.class,true,false);
//初始化intent,启动页面
ContexttargetContext =InstrumentationRegistry.getInstrumentation().getTargetContext();
Intent intent =newIntent(targetContext,
TagChooseActivity.class);
mActivityRule.launchActivity(intent);
b.ui测试
ViewMachers:寻找用来测试的View。
ViewActions:发送交互事件。
ViewAssertions:检验测试结果。
I.寻找测试的view:
onView(withId(R.id.price_num)).perform(typeText("123"),closeSoftKeyboard());
withId()通过控件id寻找控件;
withText()通过控件上的文字寻找控件;
listView:id相同可以通过控件上text方法寻找控件:
onView(allOf(withText("7"),hasSibling(withText("item: 0")))).perform(click());
II.发送交互事件:
.perform()
用户软键盘输入内容:
onView(withId(R.id.price_num)).perform(typeText("123"),closeSoftKeyboard());
点击控件事件:
onView(withId(R.id.tag_price_delete)).perform(click());
滑动页面事件:
onView(withId(R.id.lv_popup)).perform(swipeUp());
还有很多长按,双击,等用户常用手势,均在perform类中有封装。
III.检测测试结果
.check
查看ui上内容显示是否正确:
onView(withId(R.id.price_type)).check(matches(withText("人民币")));
查看控件是否存在:
onView(allOf(withId(R.id.iv_item_location),hasSibling(withText("人民币")))).check(matches(isDisplayed()));
onView(allOf(withId(R.id.iv_item_location),hasSibling(withText("美元")))).check(matches(not(isDisplayed())));
IV. check for a toast
@Test
public voidtoastCheckCase() {
onData(hasToString(containsString("Frodo"))).perform(click());
onView(withText(startsWith("Clicked:"))).
inRoot(withDecorView(
not(is(mActivityRule.getActivity().
getWindow().getDecorView())))).
check(matches(isDisplayed()));
}
c.线程安全
Espresso测试有个很强大的地方是它在多个测试操作中是线程安全的。Espresso会等待当前进程的消息队列中的UI事件,并且在任何一个测试操作中会等待其中的AsyncTask结束才会执行下一个测试。这能够解决程序中大部分的线程同步问题。
哈哈,别人的总结图,更加清晰
网友评论