大家都知道,测试Android系统原生态APP目前最好的工具使UiAutomation,随着DevOps的普及,我们需要尽早地发现程序中的缺陷,所以单元测试变得非常重要,Android系统推出了Espresso测试框架。Espresso与UiAutomation最显著区别在于UiAutomation可以测试一个APP多个界面(Active),而Espresso只能测试一个APP一个界面(Active),另外UiAutomation可以独立测试APP建立专门的Project,Espresso必须建立在待测APP同一个目录下。下面我向大家简单介绍一下Espresso。
进行Espresso,首先在待测APP的build.gradle(module.app)中作如下的配置。
android { … } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } packagingOptions{ exclude'LICENSE.txt' } } dependencies { … androidTestImplementation 'com.android.support.test:runner:0.5' androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' })}
这里特别需要注意的是:com.android.support.test:runner请使用0.5版本,最新的1.0版本有bug。
同步完成,我们在待测试代码的androidTest建立测试代码,下面是这段Espresso代码。
package com.example.espresso.demo4; import android.support.test.filters.LargeTest; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; import static android.support.test.espresso.action.ViewActions.replaceText; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.core.StringStartsWith.startsWith; import static org.hamcrest.Matchers.not; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class MainActivityInstrumentationTest { private static final String username="Guxiang"; private static final String password="123456"; @Rule public ActivityTestRule<MainActivity> mActivityRule=new ActivityTestRule<>(MainActivity.class); @Test @LargeTest public void testDemo4(){ onView(withId(R.id.username)).perform(replaceText(username),closeSoftKeyboard()); onView(withId(R.id.password)).perform(replaceText(password),closeSoftKeyboard()); onView(withText("登录")).perform(click()); onView(withText(startsWith("用户名或密码"))) .inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView()))) .check(matches(isDisplayed())); //onView(withId(R.id.tv1)).check(matches(withText(expectedText))); } }
这段代码实现的功能是,在登录页面输入错误的登录名或密码,点击【登录】案件后测试系统是否给出“用户名或密码”错误信息。
1、准备工作
package com.example.espresso.demo4;
首先保证测试代码的package与产品代码的package保持一致。
@Rule public ActivityTestRule<MainActivity> mActivityRule=new ActivityTestRule<>(MainActivity.class);
表示待测的是产品代码中的MainActivity.class模块,我们把测试模块变量赋给变量mActivityRule。
2、定位
onView(withId(R.id.username)).perform(replaceText(username),closeSoftKeyboard());
这段代码通过函数onView来执行操作,withId(R.id.username)是通过APP的R.id.username来进行定位,在这里id名为username,这里的R文件与产品代码中R.java中定义的。除了用withId定位外,还可以使用withText(String):元素的Text名,withClassName():元素的className名,withContentDescription():元素的描述信息等方法来定位。也可以采用多元素属性联合定位来实现,比如:
onView(allOf(withId(R.id.button_signin), withText("Sign-in")));
通过id为R.id.button_signin且Text为Sign-in的元素来定位。另外在定位中还可以使用no函数,表示“不”的意思,比如:
onView(allOf(withId(R.id.button_signin), not(withText("Sign-out"))));
id为R.id.button_signin但是Text不是Sign-in的元素。
除了用onView进行定位,也可以用onData进行定位。
onData(allOf(is(instanceOf(String.class)), is("Americano")));
假设一个Spinner的控件,我们要点击“Americano”,可用上面的语句来定位。同样假设是一个Listview,我们需要点击Listview中第二个item的按钮,那么我们需要这样写。
onData(Matchers.allOf()) .inAdapterView(withId(R.id.photo_gridview)) // listview的id .atPosition(1) // 所在位置 .onChildView(withId(R.id.imageview_photo)) // item中子控件id
3、操作
perform后面为对定位的元素执行操作,常用的方法有。
另外,在最上面的例子中的“closeSoftKeyboard()”表示输入字符以后收起键盘。
4、断言
一般断言如下所示。
onView(withId(R.id.tv1)).check(matches(withText(expectedText)));
方法check()表示检查, matches()表示匹配,matches()方法中的参数同定位。同matches()方法一样经常使用的,还有。
代码
onView(withText(startsWith("用户名或密码"))) .inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView()))) .check(matches(isDisplayed()));
是一个检查Toast很有用的方法,这个如果你使用UiAutomation是很难实现的。
版权声明:本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。