欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android单元测试之对Activity的测试示例

程序员文章站 2023-11-26 19:15:40
上一篇文章已经介绍了单元测试的作用和简单示例,如果不了解的读者可以先阅读上一篇android单元测试-作用以及简单示例。  这篇文章主要介绍常见的acti...

上一篇文章已经介绍了单元测试的作用和简单示例,如果不了解的读者可以先阅读上一篇android单元测试-作用以及简单示例。 

这篇文章主要介绍常见的activity中的测试。

对acitivity的测试

对于activity,我们大致有两种测试需求:

1、在activity正常启动后,查看界面布局是否正确,包括view的点击事件等是否正确。

2、需要在activity启动前完成各种数据的部署,然后查看activity的效果。

对于这两种需求,笔者分别做了两个示例解说:

1、检测一个布局中的button和textview是否正确。

2、从网络动态获取string到activity界面显示,并且这个图片的url是由intent传递过来的。

环境部署

首先要导入expresso-core的包,如下:

dependencies {
  // other dependencies ...
  androidtestcompile 'com.android.support.test.espresso:espresso-core:2.2.2'
}

当然在目前的项目架构中一般已经自动导入了这个包,所以不需要自己导入,笔者项目中自动导入的包如下如下:

dependencies {
  compile filetree(include: ['*.jar'], dir: 'libs')
  androidtestcompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
  })
  compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
  compile 'com.android.support.constraint:constraint-layout:1.0.2'
  testcompile 'junit:junit:4.12'

}

项目结构如下:

Android单元测试之对Activity的测试示例

布局view的测试:

package com.example.xujiajia_sx.myexpressotest;

import android.app.activity;
import android.os.bundle;
import android.support.annotation.nullable;
import android.view.view;
import android.widget.button;
import android.widget.textview;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class simpleviewactivity extends activity{
  private textview tv;
  private button btn;
  @override
  protected void oncreate(@nullable bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.act_simple_view);

    initview();
  }

  private void initview() {
    tv=findviewbyid(r.id.tv_simple_view);
    btn=findviewbyid(r.id.btn_simple_view);

    tv.settext("111");
    btn.settext("222");

    btn.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view view) {
        tv.settext("777");
      }
    });
  }
}

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <textview
    android:id="@+id/tv_simple_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
     />

  <button
    android:id="@+id/btn_simple_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

</linearlayout>
package com.example.xujiajia_sx.myexpressotest;

import android.support.test.rule.activitytestrule;

import org.junit.rule;
import org.junit.test;

import static android.support.test.espresso.espresso.onview;
import static android.support.test.espresso.action.viewactions.click;
import static android.support.test.espresso.assertion.viewassertions.matches;
import static android.support.test.espresso.matcher.viewmatchers.withid;
import static android.support.test.espresso.matcher.viewmatchers.withtext;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class simpleviewtest {

  @rule
  public activitytestrule<simpleviewactivity> mactivitytestrule =
      new activitytestrule<simpleviewactivity>(simpleviewactivity.class);

  @test
  public void textviewtest() throws exception {
    onview(withid(r.id.tv_simple_view))
        .check(matches(withtext("111")));
  }

  @test
  public void buttontest() throws exception {
    onview(withid(r.id.btn_simple_view))
        .check(matches(withtext("222")))
        .perform(click());
    onview(withid(r.id.tv_simple_view))
        .check(matches(withtext("777")));
  }
}

测试主要逻辑:

1、首先要使用activitytestrule初始化你要测试的activity。

2、编写测试方法,测试view是否是我们预期的样子。

两个测试方法逻辑如下:

textviewtest():

在activity中查找id为tv_simple_view的view,检查它的text是否为“111”。

buttontest():

在activity中查找id为btn_simple_view的view,检查它的text是否为“222”。然后执行点击事件,点击事件的逻辑是在activity的oncreate中设置的,是把textview的text设置为777。在执行完点击事件后,测试方法中继续测试textview的text是否为“777”。

读者可能阅读到对view的测试非常陌生,不用担心,此处主要要理解测试的逻辑即可,笔者会在下篇文章具体讲解view的各种测试方法。

网络获取string的activity测试:

package com.example.xujiajia_sx.myexpressotest;

import android.app.activity;
import android.os.bundle;
import android.support.annotation.nullable;
import android.widget.textview;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class acttestactivity extends activity{
  private textview tv;
  @override
  protected void oncreate(@nullable bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.act_act_test);

    initview();
  }

  private void initview() {
    tv= findviewbyid(r.id.tv_act_test);
    new thread(new runnable() {
      @override
      public void run() {
        string url =getintent().getstringextra("url");
        final string s=mhttpclient.getinstance().get(url);
        runonuithread(new runnable() {
          @override
          public void run() {
            tv.settext(s);
          }
        });
      }
    }).start();
  }
}

package com.example.xujiajia_sx.myexpressotest;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class mhttpclient {
  private static httpurlconnectionclient mclient = null;

  public static void setclient(httpurlconnectionclient client) {
    mclient = client;
  }

  public static httpurlconnectionclient getinstance() {
    return mclient;
  }
}

package com.example.xujiajia_sx.myexpressotest;

import android.util.log;

import java.io.bufferedreader;
import java.io.ioexception;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.net.httpurlconnection;
import java.net.url;

import static android.content.contentvalues.tag;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class httpurlconnectionclient {

  public string get(string url) {
    httpurlconnection conn = null;
    try {
      url murl = new url(url);
      conn = (httpurlconnection) murl.openconnection();
      conn.setrequestmethod("get");
      conn.setconnecttimeout(2000);
      conn.connect();
      inputstream is = conn.getinputstream();
      stringbuilder sb = new stringbuilder();
      bufferedreader reader = new bufferedreader(new inputstreamreader(is));
      string line;
      while ((line = reader.readline()) != null) {
        sb.append(line).append("\n");
      }
      reader.close();
      return sb.tostring();
    } catch (ioexception e) {
      log.e(tag, "network error for mini program ", e);
      return "";
    } finally {
      //最后将conn断开连接
      if (conn != null) {
        conn.disconnect();
      }
    }
  }


}

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <textview
    android:id="@+id/tv_act_test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />


</linearlayout>



package com.example.xujiajia_sx.myexpressotest;

import android.content.intent;
import android.support.test.rule.activitytestrule;

import org.junit.rule;
import org.junit.test;

/**
 * created by xujiajia_sx on 2017/8/14.
 */

public class acttest {
  @rule
  public activitytestrule<acttestactivity> mactivitytestrule=
      new activitytestrule<acttestactivity>(acttestactivity.class){
        @override
        protected intent getactivityintent() {
          intent intent=new intent();
          intent.putextra("url","http://www.weather.com.cn/adat/sk/101310201.html");
          return intent;
        }

        @override
        protected void beforeactivitylaunched() {
          mhttpclient.setclient(new httpurlconnectionclient());
        }
      };

  @test
  public void mtest() throws exception{

    thread.sleep(5000);
  }


}

网络获取不要忘记在androidmanifest中加网络权限喔。

这个activity的主要逻辑就是接收intent,然后获取到传过来的url,接着通过网络获取到url的string,显示到textview上。

主要测试逻辑:

首先还是要定义activitytestrule,确定使用哪个activity。

与前一个例子不同的是,这里要重写activitytestrule的两个方法,getactivityintent() 和beforeactivitylaunched()。顾名思义,一个是设置activity获取到的intent,另一个是设置activity启动跟之前的准备工作。

笔者此处在getactivityintent() 中设置了传递的url,在beforeactivitylaunched()设置的网络获取的方式。

有些读者可能会好奇为什么网络获取的方式不默认呢,而要通过setclient()来设置?

因为这样可以更方便我们测试,在正式的项目中,我们可能会需要在代码中加入log等操作,但是正式的代码一般我们是不会去修改的,但是我们可以继承它,重写某些方法,然后把它放到测试需要的地方。

在这里我们就可以继承httpurlconnectionclient 这个类,然后把继承的子类使用setclient()来作为网络获取的方式。

总结

activity的使用方法大致如此了,如果有更多需求的读者可以查看一下官方activitytestrule的reference。

链接如下:https://developer.android.google.cn/reference/android/support/test/rule/activitytestrule.html

第一种使用方法中设计到了对view的测试,由于篇幅较大,本篇文章未能详细讲述,笔者会在下篇文章做一定讲解。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。