Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android利用Espresso进行UI自动化测试

Android利用Espresso进行UI自动化测试的方法详解

作者:安卓干货营

因为我是搞android开发的,所以被分到了自动化测试小组,所以了解了一些UI自动化测试。下面这篇文章主要给大家介绍了关于Android利用Espresso进行UI自动化测试的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。

为什么需要UI自动化测试?

我有一个观点,对于重复的工作,那么程序都是可以代替的,我想这是作为一个程序员的一个基本素养(能偷懒的绝不干活)。UI自动化测试就是为了应付一些重复的工作,比如说测试某个功能,那么从应用点击,再经过一系列的点击页面才能到达这个页面,然后进行测试,那么我们是不是可以写段代码让app自动跑起来,自动来到那个界面进行测试呢?答案是肯定的,这就是本文所要说的自动化测试。

引言

谷歌2013年的时候开源了espress,谷歌的思路是,等到它足够成熟和稳定以后,将其迁移到Android SDK中,以此可见对他的重视。Google使用Espresso测试了他们自己的超过30个应用程序,包括G+、Maps和Drive。

Espresso测试是非常容易实现的,由三步构成:

先看下官方给的示例,就能理解以上的三个步骤:

onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher  
 .perform(click()) // click() is a ViewAction
 .check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion

Espresso框架是google官方大力推荐的一套测试框架,所以无论如何都要学习一下的.另外,自Android Studio2.2版本开始,google就为Espresso框架内置了一个图形化界面,用来自动生成单元测试代码。

接下来一起写一demo测试,深入了解Espresso。

准备

支持Espresso:

dependencies {
 ...
 testCompile 'junit:junit:4.12'
 androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2', {
 exclude group: 'com.android.support', module: 'support-annotations'
 }
}

在dependencies中添加,一般默认会有testCompile 'junit:junit:4.12',所以我们只需添加另一句即可。

defaultConfig{
 ...
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

在defaultConfig中添加如上语句,支持测试运行。

创建Test类

特别注意,该类应在androidTest文件夹下


举个简单例子:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityInstrumentationTest {
 @Rule
 public ActivityTestRule mActivityRule = new ActivityTestRule<>(
   MainActivity.class);
 @Test
 public void sayHello(){
  onView(withText("Say hello!")).perform(click());
  onView(withId(R.id.textView)).check(matches(withText("Hello, World!")));
 }
}

@Rule

@Rule
public ActivityTestRule mTestRule = new ActivityTestRule<>(MainActivity.class);

这句话就定义了一个测试规则,可以看到构造方法的参数里指定了一个 MainActivity.class, 具体的体现就是当你运行这段测试代码时,app将会直接打开 MainActivity界面然后进行你所定义的测试用例。 所以当你想直接测试某个界面时,你可以把那个界面填到这个参数里,这样就直接打开你指定的界面进行测试了。

@Test

@Test
public void testLogin() {
 ...
}

定义一个测试方法,当你的测试类运行时,所执行的代码就是Test注解下的方法(Espresso还提供了其他的一些注解: 比如@After,@Before等,具体的用法可以去我上面写的android官网上查看),当然上面那段代码对应的就是testLogin测试方法,testLogin方法里所定义的就是要测试的内容。

ViewMachers 查找View

使用onView方法找到view:其中参数可以是withId(通过资源id查找),withText(通过显示内容查找)有多个约束条件时,可以使用allOf  如allOf(withText("Hello") ,withId(R.id.hello))

注意:

ViewActions 执行事件

对View的操作:perform()方法  方式是onView(...).perform() 。也可以执行多个操作在一个perform中如:perform(click(),clearText())

所有的操作都有一个前提 ———— 就是要执行的view必须在当前界面上显示出来(有且可见)。

方法名 含义
click() 点击view
clearText() 清除文本内容
swipeLeft() 从右往左滑
swipeRight() 从左往右滑
swipeDown() 从上往下滑
swipeUp() 从下往上滑
click() 点击view
closeSoftKeyboard() 关闭软键盘
pressBack() 按下物理返回键
doubleClick() 双击
longClick() 长按
scrollTo() 滚动
replaceText() 替换文本
openLinkWithText() 打开指定超链

ViewAssertions 检验结果

使用check()方法来检查View是否符合我们的期望: onView(...).check() 检查view中是否含有文本“hello”              check(matches(withText("hello")))

看下我写的示例

我们基本所有的app都有登录功能,都需要呼入用户名和密码,那么在点击登录之前需要对用户名和密码进行非空、格式等验证。

以下示例我们点击登录按钮时,首先对输入的用户名和密码进行验证,验证不通过在TextView上显示对应原因,验证没有问题显示“登录成功”。

Activity界面及逻辑

 @Override
 public void onClick(View view) {
  if (view.getId() == R.id.bt_login) {
   login();
  }
 }
 /**
  * 去登录
  */
 private void login() {
  String name = et_name.getText().toString().trim();
  String pwd = et_pwd.getText().toString().trim();
  if (TextUtils.isEmpty(name)) {
   tv_login_result.setText("用户名为空");
   return;
  }
  if (name.length() < 6 ) {
   tv_login_result.setText("用户名格式错误");
   return;
  }
  if (TextUtils.isEmpty(pwd)) {
   tv_login_result.setText("密码为空");
   return;
  }
  if (pwd.length() < 6 ) {
   tv_login_result.setText("密码格式错误");
   return;
  }
  tv_login_result.setText("登录成功");
 }

其他代码忽略。

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityTest {
 private String[] names = {"", "a", "123123"};
 private String[] pwds = {"", "a", "123123"};
 @Rule
 public ActivityTestRule mTestRule = new ActivityTestRule<>(MainActivity.class);
 @Before
 public void init() {
  Log.e("TAG", "init: ");
 }
 @Test
 public void testLogin() {
  // 不做任何输入,直接点击登录
  onView(allOf(withId(R.id.bt_login), isDisplayed())).perform(click());
  onView(allOf(withId(R.id.tv_login_result), isDisplayed())).check(matches(withText("用户名为空")));
  // 用户名是空,点击登录
  onView(allOf(withId(R.id.et_name), isDisplayed())).perform(replaceText(names[0]), closeSoftKeyboard());
  onView(allOf(withId(R.id.bt_login), isDisplayed())).perform(click());
  onView(allOf(withId(R.id.tv_login_result), isDisplayed())).check(matches(withText("用户名为空")));
  // 用户名格式错误,点击登录
  onView(allOf(withId(R.id.et_name), isDisplayed())).perform(replaceText(names[1]), closeSoftKeyboard());
  onView(allOf(withId(R.id.bt_login), isDisplayed())).perform(click());
  onView(allOf(withId(R.id.tv_login_result), isDisplayed())).check(matches(withText("用户名格式错误")));
  // 用户名和密码都正确,点击登录
  onView(allOf(withId(R.id.et_name), isDisplayed())).perform(replaceText(names[2]), closeSoftKeyboard());
  onView(allOf(withId(R.id.et_pwd), isDisplayed())).perform(replaceText(pwds[2]), closeSoftKeyboard());
  onView(allOf(withId(R.id.bt_login), isDisplayed())).perform(click());
  onView(allOf(withId(R.id.tv_login_result), isDisplayed())).check(matches(withText("登录成功")));
 }
}

这里我们事先定义了一些测试数据,使用Espresso进行模拟各种情况输入和点击,测试是否符合我们的预期:

对Espresso的介绍大概就是这些了,希望大家多提建议,一起进步。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

您可能感兴趣的文章:
阅读全文