当前位置: 首页 > 编程笔记 >

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

墨阳羽
2023-03-14
本文向大家介绍Android利用Espresso进行UI自动化测试的方法详解,包括了Android利用Espresso进行UI自动化测试的方法详解的使用技巧和注意事项,需要的朋友参考一下

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

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

引言

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

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

  • ViewMachers:寻找用来测试的View。
  • ViewActions:发送交互事件。
  • ViewAssertions:检验测试结果

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

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文件夹下


  • androidTest:进行与Android相关(如调用Android设备等)测试;
  • test:进行简单的只涉及java SE相关的测试。

举个简单例子:

@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!")));
 }
}
  • 首先需要在测试用例类的类体前添加@RunWith的注解,并设置测试运行平台为AndroidJUnit4
  • 如果允许测试需要较大消耗,可以使用@LargeTest注解
  • 设置ActivityTestRule用来指明被测试的Activity,使用@Rule注解
  • 测试方法必须以 test 开头,并且使用@Test注解(否则会报找不到方法异常)

@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))

注意:

  • 无论是通过withId()找控件还是通过withText()找控件,或者其他方式比如 withClassName() ,withResourceName() ,withTagKey()等方法,都要一定保证你所找的控件在当前页面确实存在且可见。
  • 如果要测试AdapterView ,比如 ListView 或GridView等,使用上面的onView()方法是无效的,因为AdapterView的布局item是动态呈现的,没法直接指定,所以当要测试AdapterView时,请把onView()方法换成onData() 方法,与onView()方法返回ViewInteraction类似,onData()方法返回DataInteraction,二者用法基本都是一样的。

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的介绍大概就是这些了,希望大家多提建议,一起进步。

总结

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

 类似资料:
  • 我有一些问题设置/运行espresso测试的Android。我的TestClass如下所示:- 在设备仿真器-5554上启动检测Android.test.InstrumentationTestRunner 向Eclipse发送测试信息 测试完成 没有提到运行测试,测试也不会运行。我会错过什么?

  • 本文向大家介绍利用Jasmine对Angular进行单元测试的方法详解,包括了利用Jasmine对Angular进行单元测试的方法详解的使用技巧和注意事项,需要的朋友参考一下 前言 本文主要介绍的是关于利用Jasmine对Angular单元测试的相关内容,以下是我假定那些极少或压根没写单元测试的人准备的,因此,会白话解释诸多概念性问题,同时会结合 Jasmine 与之对应的方法进行讲解。 一、概念

  • 自动化测试将被用于进一步的任务中,并且还将被广泛应用在实际项目中。 为什么我们需要测试? 当我们在写一个函数时,我们通常可以想象出它应该做什么:哪些参数会给出哪些结果。 在开发期间,我们可以通过运行程序来检查它并将结果与预期进行比较。例如,我们可以在控制台中这么做。 如果出了问题 —— 那么我们会修复代码,然后再一次运行并检查结果 —— 直到它工作为止。 但这样的手动“重新运行”是不完美的。 当通

  • Android Espresso UI测试与模拟改型API 模拟服务器请求Android Espresso UI测试 这是我最新的实验: 以下是改型实例: MainActivity开始,其中有的实例: 我想一些东西,可以简单地围绕着改型的实例,并弹出一个URL,但我99%肯定这是不现实的。如果有任何swift开发人员在研究这个问题,我希望找到与类似的功能。 那么,我能以某种方式为改型实例设置URL

  • 本文向大家介绍Angular.Js的自动化测试详解,包括了Angular.Js的自动化测试详解的使用技巧和注意事项,需要的朋友参考一下 本文着重介绍关于ng的测试部分,主要包括以下三个方面: 框架的选择(Karma+Jasmine) 测试的分类和选择(单元测试 + 端到端测试) 在ng中各个模块如何编写测试用例 下面各部分进行详细介绍。 测试的分类 在测试中,一般分为单元测试和端到端测试,单元测试

  • 通过Jenkins并行完成UI的自动化测试 原文链接 : Concurrent Android UI automation with Jenkins 原文作者 : Ha Duy Trung 译文出自 : 开发技术前线 www.devtf.cn 译者 : chaossss 校对者: tiiime 状态 : 完成 现在的 IT 公司会为了进入不同的市场开发相应的 App,来自同一家公司的 App 总会