zoukankan      html  css  js  c++  java
  • Android随笔之——Android单元测试

      在实际开发中,开发android软件的过程需要不断地进行测试。所以掌握Android的单元测试是极其重要的。您应该把单元测试作为Android应用开发周期的一部分,精心编写的测试可以在开发早起帮你发现错误。

      关于Android单元测试可以看Google官方给的教程:Best Practices for Testing(需要翻墙)

    一、创建Android Test Project

      1、创建一个Android Project:Hello。并将其布局文件改成如下:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:orientation="vertical" >
     6 
     7     <TextView
     8         android:id="@+id/text"
     9         android:layout_width="match_parent"
    10         android:layout_height="wrap_content"
    11         android:text="@string/hello_world" />
    12 
    13     <!-- 这样直接写字符串是不好的,建议写在strings.xml中 -->
    14     <EditText
    15         android:id="@+id/edit"
    16         android:layout_width="match_parent"
    17         android:layout_height="wrap_content"
    18         android:hint="请输入" />
    19 
    20 </LinearLayout>

      2、创建Hello对应的测试项目:File->New->Other->Android->Android Test Project,弹出”New Android Test Project”对话框,在"Project Name"中输入“HelloTest”,点击“Next”。

      3、在”Select Test Target”中,选中你要测试的Android项目,然后点击Finish即可。

      创建完Android Test Project后,打开HelloTest项目的AndroidManifest.xml文件,你会发现里面的配置会比HelloTest多,具体不同请看下面的代码:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.lsj.hello.test"
     4     android:versionCode="1"
     5     android:versionName="1.0" >
     6 
     7     <uses-sdk android:minSdkVersion="8" />
     8 
     9     <!-- 代表配置单元测试框架的启动装置,启动装置有好几个类,可以选择,一般情况下我们使用上面这个 -->
    10     <!-- targetPackage与Hello的package相同,代表单元测试框架和当前应用是处于同一个进程中 -->
    11     <instrumentation
    12         android:name="android.test.InstrumentationTestRunner"
    13         android:targetPackage="com.lsj.hello" />
    14 
    15     <application
    16         android:icon="@drawable/ic_launcher"
    17         android:label="@string/app_name" >
    18         <!-- 代表把单元测试框架中的一些依赖库引入进来 -->
    19         <uses-library android:name="android.test.runner" />
    20     </application>
    21 
    22 </manifest>

     

    二、单元测试代码编写

      1、创建完Android Test Project后,你会发现HelloTest自动帮你创建了com.lsj.hello.tests的包名。关于Android单元测试相关包、类、方法的命名方式如下:

    包名:com.lsj.example————com.lsj.example.tests//对应包名+".tests"
    类名:Hello.java————HelloTest.java//对应类名+"Test"
    方法名:Hello()————testHello()//"test"+对应方法名

      2、在com.lsj.hello.tests包下建立MainActivityTest.java类,MainActivityTest继承自ActivityInstrumentationTestCase2,关于Android测试类可以看文章末尾的链接

      3、编辑MainActivityTest,添加单元测试代码

      1 package com.lsj.hello.test;
      2 
      3 import android.app.Instrumentation;
      4 import android.test.ActivityInstrumentationTestCase2;
      5 import android.view.KeyEvent;
      6 import android.widget.EditText;
      7 import android.widget.TextView;
      8 
      9 import com.lsj.hello.MainActivity;
     10 
     11 /**
     12  * ActivityInstrumentationTestCase2继承于TestCase, TestCase类位于junit.framework包下
     13  * 查阅Android API文档,可以发现Android的测试类全部继承自TestCase。 创建一个单元测试大致需要以下步骤:
     14  * 
     15  * <pre>
     16  * 1、继承TestCase类或其子类
     17  * 2、定义要使用到的实例变量 
     18  * 3、使用setUp()方法,在测试前的对变量和测试环境进行初始化 
     19  * ....测试 
     20  * 4、在测试完成后进行垃圾回收等善后工作
     21  * </pre>
     22  * 
     23  * @author Lion
     24  */
     25 public class MainActivityTest extends
     26         ActivityInstrumentationTestCase2<MainActivity> {
     27 
     28     private MainActivity mActivity;
     29     private TextView mTextView;
     30     private EditText mEditText;
     31     private Instrumentation mInstrumentation;
     32 
     33     /**
     34      * 重写MainActivityTest的构造方法,注意super内必须为<>内的泛型类,否则会报错。
     35      * 根据Google官方给的示例,其构造函数为午餐,而且测试的时候发现有参的构造函数会导致单元测试失败。
     36      */
     37     public MainActivityTest() {
     38         super(MainActivity.class);
     39     }
     40 
     41     @Override
     42     protected void setUp() throws Exception {
     43         /* 执行对变量和测试环境的初始化 */
     44         super.setUp();
     45         // 关闭touch模式,否则key事件会被忽略
     46         setActivityInitialTouchMode(false);
     47 
     48         mInstrumentation = getInstrumentation();
     49 
     50         // 获取被测试的MainActivity
     51         mActivity = this.getActivity();
     52         // 获取被测试的TextView控件
     53         mTextView = (TextView) mActivity.findViewById(com.lsj.hello.R.id.text);
     54         // 获取被测试的EditText控件
     55         mEditText = (EditText) mActivity.findViewById(com.lsj.hello.R.id.edit);
     56     }
     57 
     58     /**
     59      * 测试数据初始化是否为空
     60      */
     61     public void testInit() {
     62         // 断言mActivity是否为空
     63         assertNotNull(mActivity);
     64         // 断言mTextView是否为空
     65         assertNotNull(mTextView);
     66         // 断言mEditText是否为空
     67         assertNotNull(mEditText);
     68     }
     69 
     70     /**
     71      * 测试文本框字符串是否相等
     72      */
     73     public void testTextViewString() {
     74         // 断言mTextView显示的文本是否与String.xml中的hello_world相等
     75         assertEquals(
     76                 mActivity.getResources().getString(
     77                         com.lsj.hello.R.string.hello_world), mTextView
     78                         .getText().toString());
     79     }
     80 
     81     /**
     82      * 测试输入
     83      */
     84     public void testEditTextInput() {
     85         input();
     86         assertEquals("hello", mEditText.getText().toString());
     87     }
     88 
     89     /**
     90      * 模拟输入
     91      */
     92     public void input() {
     93         /* UI组件的相关操作需要在UI线程上进行,所以用Activity的runOnUiThread方法 */
     94         mActivity.runOnUiThread(new Runnable() {
     95             @Override
     96             public void run() {
     97                 mEditText.requestFocus();
     98                 mEditText.performClick();
     99             }
    100         });
    101         /*
    102          * 由于测试用例在单独的线程上执行,所以此处需要同步application,
    103          * 调用waitForIdleSync等待测试线程和UI线程同步,才能进行输入操作。
    104          * waitForIdleSync和sendKeys不允许在UI线程里运行
    105          */
    106         mInstrumentation.waitForIdleSync();
    107         // 调用sendKeys方法,输入
    108         sendKeys(KeyEvent.KEYCODE_H, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_L,
    109                 KeyEvent.KEYCODE_L, KeyEvent.KEYCODE_O);
    110     }
    111 
    112     @Override
    113     protected void tearDown() throws Exception {
    114         /* 在测试完成后进行垃圾回收等工作 */
    115         super.tearDown();
    116     }
    117 }

      这样,一个关于用户输入的单元测试就写完了,关于单元测试相关类的介绍可以查看这篇博客:Android Instrumentation

    源码下载:百度云盘

    作者:登天路

    转载请说明出处:http://www.cnblogs.com/travellife/

  • 相关阅读:
    如何装配vixta之一如何利用Nero将vixta刻录成ISO光盘
    48条经典的Windows小技巧
    再学 GDI+[85]: TGPImage(5) RotateFlip 旋转与镜像
    再学 GDI+[84]: TGPImage(4) 把图像显示在指定的矩形中
    再学 GDI+[83]: TGPImage(3) 平行四边形变换
    一个用 GDI+ 给图片添加花边的例子 给 "sky123" 做的
    再学 GDI+[82]: TGPImage(2) GetThumbnailImage 略缩图
    再学 GDI+[81]: TGPImage(1) 显示图像
    再学 GDI+[86]: TGPImage(6) 拖动图像
    再学 GDI+[88]: TGPImage(8) 放大镜
  • 原文地址:https://www.cnblogs.com/travellife/p/4109896.html
Copyright © 2011-2022 走看看