搬砖之余来一杯意式浓缩咖啡(Espresso)

就知道,这肯定是杯假咖啡,搬砖还有时间喝咖啡!!!

年轻人,别急躁吗,看完之后,你会发现可能真的可以空出一大把时间去喝咖啡了。

我信了你的邪了。

…,不信?你就往下看呗

  • 何为意式浓缩咖啡(Espresso)
  • 几种UI自动化测试工具的比较
  • 基础用法
  • 进阶使用

何为意式浓缩咖啡(Espresso)?

Espresso是Google的开源自动化测试框架。相对于Robotium和UIAutomator,它的特点是规模更小、更简洁,API更加精确,编写测试代码简单,容易快速上手。因为是基于Instrumentation的,所以不能跨App

几种UI自动化测试工具的比较

那相比较其他自动化测试工具,有什么不一样呢?

Monkey

Monkey是Android SDK自带的测试工具,在测试过程中会向系统发送伪随机的用户事件流,如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试,也有日志输出。实际上该工具只能做程序做一些压力测试,由于测试事件和数据都是随机的,不能自定义,所以有很大的局限性

Instrumentation

Instrumentation是早期Google提供的Android自动化测试工具类,虽然在那时候JUnit也可以对Android进行测试,但是Instrumentation允许你对应用程序做更为复杂的测试,甚至是框架层面的。通过Instrumentation你可以模拟按键按下、擡起、屏幕点击、滚动等事件。Instrumentation是通过将主程序和测试程序运行在同一个进程来实现这些功能,你可以把Instrumentation看成一个类似Activity或者Service并且不带界面的组件,在程序运行期间监控你的主程序。缺点是对测试人员来说编写代码能力要求较高,需要对Android相关知识有一定了解,还需要配置AndroidManifest.xml文件,不能跨多个App

UiAutomator

UiAutomator也是Android提供的自动化测试框架,基本上支持所有的Android事件操作,对比Instrumentation它不需要测试人员了解代码实现细节(可以用UiAutomatorviewer抓去App页面上的控件属性而不看源码)。基于Java,测试代码结构简单、编写容易、学习成本,一次编译,所有设备或模拟器都能运行测试,能跨App(比如:很多App有选择相册、打开相机拍照,这就是跨App测试)。缺点是只支持SDK 16(Android 4.1)及以上,不支持Hybird App、WebApp

配置Espresso

1.打开app/build.gradle

在dependencies节点下添加以下库:

androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestCompile 'com.android.support.test:rules:1.0.2'

2.在android.defaultConfig下添加下面的代码
 defaultConfig {
        //...省略
       "android.support.test.runner.AndroidJUnitRunner"
    }

基础用法

下面写一个简单的Demo来学习一下它的基础用法

1.先写一个Activity用来测试

里面有一个按钮,点击它,里面的文本会改变

MainActivity的代码如下,xml文件省略

public class MainActivity extends AppCompatActivity {
    Button btClick;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btClick=(Button)findViewById(R.id.bt_click);
        btClick.setText("click me");
    }
    
    public void clickButton(View view){
        btClick.setText("learn espresso");
    }
}

2.在src/androidTest/java/com.example.package/路径下新建一个测试类

MyEspressoTest.class

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyEspressoTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
    
    @Test
    public void clickButton(){

        //检查文本是不是Hello World,并点击一下按钮
        onView(withId(R.id.bt_click))
                .check(matches(withText("Hello World!")))
                .perform(click());

        //检验按钮上的文本是否修改
        onView(withId(R.id.bt_click))
                .check(matches(withText("learn espresso")));


    }
}
3.运行该测试

run test.png

观察模拟器的动作变化

模拟器它会自动点击按钮并更改按钮的文本内容

运行结束观察控制台的测试结果

可以看到所有测试通过
test result.png

进阶使用

接下来我们实现一个登录的测试

修改MainActivity

如果用户名为jasonking,密码为123,则登录按钮文本变为登录成功,否则变为登录失败

MainActivity.class

public class MainActivity extends AppCompatActivity {
    EditText edName;
    EditText edPass;
    Button btClick;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btClick=(Button)findViewById(R.id.bt_click);
        edName=(EditText) findViewById(R.id.ed_username);
        edPass=(EditText) findViewById(R.id.ed_pass);
        btClick.setText("登录");
    }

    public void clickButton(View view){
        if(edName.getText().toString().equals("jasonking")&&edPass.getText().toString().equals("123")){
            btClick.setText("登录成功");
        }else{
            btClick.setText("登录失败");
        }
    }
}

修改测试类

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyEspressoTest {
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void clickLogin(){
        //清空文本框,然后输入用户名jasonking,关闭软键盘
        onView(withId(R.id.ed_username))
                .perform(
                        clearText(),
                        replaceText("jasonking"),
                        closeSoftKeyboard()
                )
                .check(matches(withText("jasonking")));
        
        //清空文本框,然后输入密码123,关闭软键盘
        onView(withId(R.id.ed_pass))
                .perform(
                        clearText(),
                        replaceText("123"),
                        closeSoftKeyboard()
                )
                .check(matches(withText("123")));



        //点击按钮检查文本是不是登录
        onView(withId(R.id.bt_click))
                .check(matches(withText("登录")))
                .perform(click());

        //检验按钮上的文本是不是登录成功
        onView(withId(R.id.bt_click))
                .check(matches(withText("登录成功")));
    }
}

运行,它会自动填写用户名和密码并点击登录按钮

test screen.png

最后验证登录按钮文本是否变为登录成功,看看控制台结果是pass的

上面只是介绍了Espresso的一小部分内容,关于Espresso还有更多的用法,不想看英文官方文档的,为你准备一份中文文档

Espresso中文文档

下一篇博客会介绍在有网络请求的情况下,我们怎么进行测试。因为并非所有的UI操作都是同步响应的。也就是说我们的UI更新需要等待网络返回结果。如果我们直接测试,那么很大概率会报错,因为在我们要测试数据是否展示在UI上时,网络数据很有可能还没有获取到。。这种情况该怎么办呢,好期待笔者的下篇博客哦[假装很期待]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章