Android使用Espresso进行UI自动化测试

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

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

  • ViewMachers:寻找用来测试的View。bash

  • ViewActions:发送交互事件。微信

  • ViewAssertions:检验测试结果app

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

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框架内置了一个图形化界面,用来自动生成单元测试代码。ide

接下来一块儿写一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!")));
    }
}
复制代码
  1. 首先须要在测试用例类的类体前添加@RunWith的注解,并设置测试运行平台为AndroidJUnit4
  2. 若是容许测试须要较大消耗,可使用@LargeTest注解
  3. 设置ActivityTestRule用来指明被测试的Activity,使用@Rule注解
  4. 测试方法必须以 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的介绍大概就是这些了,但愿你们多提建议,一块儿进步。

获取更多精彩内容,关注个人微信公众号——Android机动车

相关文章
相关标签/搜索