Android系列----JUnit单元测试的使用

【正文】

一、单元测试的引入:

如果只是普通的一个小程序,编写测试是有些多此一举,但是当项目比较庞大的时候,一般都应该去编写单元测试。JUnit测试是白盒测试,即主要是程序员自己对开发的方法进行功能性测试。JUnit是一套框架,Android中也沿用了这一套框架。

在Android中使用JUnit测试大致分如下几个步骤

  • (1)在AndroidManifest.xml中增加对JUnit的支持,并制定测试项目包。
  • (2)在AndroidManifest.xml中<application.../>节点中增加一个<uses-library...>节点,name属性为android.test.runner。
  • (3)在编写待测试方法后,新建一个类,继承AndroidTestCase,在其中编写测试用例代码。
  • (4)鼠标左键在测试用例方法上,Run As→Android JUnit Test。

 

二、步骤详解:

(1)配置清单文件:

新建Android工程文件,命名为m05_SharedPreferencesTest,

首先在AndroidManifest.xml添加一个Instrumentation:

指定Instrumentation的name与TargetPackage:

然后保存。

紧接着在<application.../>节点中增加<uses-library android:name="android.test.runner" />。

完成后,AndroidManifest.xml代码如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.example.m05_sharedpreferencestest"
 4     android:versionCode="1"
 5     android:versionName="1.0" >
 6
 7     <uses-sdk
 8         android:minSdkVersion="8"
 9         android:targetSdkVersion="16" />
10
11     <instrumentation
12         android:name="android.test.InstrumentationTestRunner"
13         android:targetPackage="com.example.m05_sharedpreferencestest" >
14     </instrumentation>
15
16     <application
17         android:allowBackup="true"
18         android:icon="@drawable/ic_launcher"
19         android:label="@string/app_name"
20         android:theme="@style/AppTheme" >
21         <uses-library android:name="android.test.runner" />
22
23         <activity            android:name="com.example.m05_sharedpreferencestest.MainActivity"
24             android:label="@string/app_name" >
25             <intent-filter>
26                 <action android:name="android.intent.action.MAIN" />
27
28                 <category android:name="android.intent.category.LAUNCHER" />
29             </intent-filter>
30         </activity>
31     </application>
32
33 </manifest>

上方11至14行以及21行是我们所添加的代码。

编写一个类,我们需要做的是在里面实现记住密码的功能:

通过SharedPreferences保存用户输入的用户名、密码:

package com.example.m05_sharedpreferencestest;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class LoginService {

    private Context context; //为了获取SharedPreferences这个类,我们需要一个上下文对象
    public LoginService(Context context) {
        // TODO Auto-generated constructor stub
        this.context = context;
    }

    //方法:通过SharedPreferences保存用户输入的用户名、密码
    public boolean saveLoginMsg(String name,String pwd) {
        boolean flag = false;
        SharedPreferences sp = context.getSharedPreferences("login", 0);
        Editor editor = sp.edit();
        editor.putString("username", name);
        editor.putString("password", pwd);
        flag = editor.commit();
        return flag;
    }
}

编写一个测试类,这个类需要继承AndroidTestCase,针对上面的方法进行测试:

package com.example.m05_sharedpreferencestest;

import android.test.AndroidTestCase;
import android.util.Log;

public class Mytest extends AndroidTestCase {

    public Mytest() {
        // TODO Auto-generated constructor stub
    }

    public void save(){
        LoginService loginService = new LoginService(getContext());
        boolean flag =  loginService.saveLoginMsg("smyhvae", "smyh");
        //如果数据保存成功,saveLoginMsg()方法将返回true值。
        Log.i("Mytest", ""+flag);
    }
}

现在来运行单元测试中的这个方法。右键选中save()方法,选中run as -->Android JUnit Test:

当执行成功后,会显示绿色,如果是其他颜色,则出错:

我们同样也能在login.xml文件中查看到内容:

我们刚刚保存的只是字符串类型。如果想要保存任何数据类型,可以在LoginService.java中添加如下方法:

    public boolean saveSharePreference(String fileName, Map<String, Object> map) {
        boolean flag = false;
        SharedPreferences preferences = context.getSharedPreferences(fileName,
                Context.MODE_PRIVATE);
        Editor editor = preferences.edit();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object object = entry.getValue();
            if (object instanceof Boolean) {
                Boolean new_name = (Boolean) object;
                editor.putBoolean(key, new_name);
            } else if (object instanceof Integer) {
                Integer integer = (Integer) object;
                editor.putInt(key, integer);
            } else if (object instanceof Float) {
                Float f = (Float) object;
                editor.putFloat(key, f);
            } else if (object instanceof Long) {
                Long l = (Long) object;
                editor.putLong(key, l);
            } else if (object instanceof String) {
                String s = (String) object;
                editor.putString(key, s);
            }
        }
        flag = editor.commit();
        return flag;
    }

运行单元测试后,msg.xml中的内容如下:

我们既然将数据存进去了,然后想将它读出来。需要再增加一个方法。代码实现见下面的内容。

 

【代码汇总】

总的来说,完整版代码如下:

LoginService.java代码如下:

 1 package com.example.m05_sharedpreferencestest;
 2
 3 import java.util.Map;
 4 import android.content.Context;
 5 import android.content.SharedPreferences;
 6 import android.content.SharedPreferences.Editor;
 7
 8 public class LoginService {
 9
10     private Context context; //为了获取SharedPreferences这个类,我们需要一个上下文对象
11     public LoginService(Context context) {
12         // TODO Auto-generated constructor stub
13         this.context = context;
14     }
15
16     //方法:通过SharedPreferences保存用户输入的用户名、密码(字符串类型)
17     public boolean saveLoginMsg(String name,String pwd) {
18         boolean flag = false;
19         SharedPreferences sp = context.getSharedPreferences("login", 0);
20         Editor editor = sp.edit();
21         editor.putString("username", name);
22         editor.putString("password", pwd);
23         flag = editor.commit();
24         return flag;
25     }
26
27     //方法:通过SharedPreferences保存用户输入的用户名、密码(各种数据类型)
28     public boolean saveSharePreference(String fileName, Map<String, Object> map) {
29         boolean flag = false;
30         SharedPreferences preferences = context.getSharedPreferences(fileName,
31                 Context.MODE_PRIVATE);
32         Editor editor = preferences.edit();
33         for (Map.Entry<String, Object> entry : map.entrySet()) {
34             String key = entry.getKey();
35             Object object = entry.getValue();
36             if (object instanceof Boolean) {
37                 Boolean new_name = (Boolean) object;
38                 editor.putBoolean(key, new_name);
39             } else if (object instanceof Integer) {
40                 Integer integer = (Integer) object;
41                 editor.putInt(key, integer);
42             } else if (object instanceof Float) {
43                 Float f = (Float) object;
44                 editor.putFloat(key, f);
45             } else if (object instanceof Long) {
46                 Long l = (Long) object;
47                 editor.putLong(key, l);
48             } else if (object instanceof String) {
49                 String s = (String) object;
50                 editor.putString(key, s);
51             }
52         }
53         flag = editor.commit();
54         return flag;
55     }
56
57     //方法:数据存储之后,然后读出来
58     public Map<String, ?> getSharePreference(String fileName) {
59         Map<String, ?> map = null;
60         SharedPreferences preferences = context.getSharedPreferences(fileName,
61                 Context.MODE_PRIVATE);
62         map = preferences.getAll();
63         return map;
64     }
65
66 }

MyTest.java代码如下:

 1 package com.example.m05_sharedpreferencestest;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6 import android.test.AndroidTestCase;
 7 import android.util.Log;
 8
 9 public class Mytest extends AndroidTestCase {
10
11     private final String TAG = "Mytest";
12     public Mytest() {
13         // TODO Auto-generated constructor stub
14     }
15
16     public void save(){
17         LoginService loginService = new LoginService(getContext());
18         boolean flag =  loginService.saveLoginMsg("smyhvae", "smyh");
19         //如果数据保存成功,saveLoginMsg()方法将返回true值。
20         Log.d(TAG, ""+flag);
21     }
22
23
24     public void save2() {
25         LoginService service = new LoginService(getContext());
26         Map<String, Object> map = new HashMap<String, Object>();
27         map.put("name", "jack");
28         map.put("age", 23);
29         map.put("salary", 3000.0f);
30         map.put("id", 1010010101l);
31         map.put("isManager", true);
32         boolean flag = service.saveSharePreference("msg", map);
33         Log.i(TAG, "--->>" + flag);
34     }
35
36
37     public void read() {
38         LoginService service = new LoginService(getContext());
39         Map<String, ?> map = service.getSharePreference("msg");
40         Log.i(TAG, "--->" + map.get("name"));
41         Log.i(TAG, "--->" + map.get("age"));
42         Log.i(TAG, "--->" + map.get("salary"));
43         Log.i(TAG, "--->" + map.get("id"));
44         Log.i(TAG, "--->" + map.get("isManager"));
45     }
46 }

如果执行read()方法的单元测试,后台输出如下:

 

三、常见测试方法:

黑盒测试: 是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。

白盒测试: 又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。

单元测试: 又称模块测试,是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。

功能测试: 根据产品特性、操作描述和用户方案,测试一个产品的特性和可操作行为以确定它们满足设计需求。

压力测试: 主体向被观察者布置一定量任务和作业,借以观察个体完成任务的行为。

集成测试: 是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口

备注:黑盒测试,不看代码结构,从用户的角度测试功能,例如玩某一款游戏来测试。白盒测试:通过代码测试功能。

时间: 2024-09-15 13:27:41

Android系列----JUnit单元测试的使用的相关文章

Android下junit单元测试、logCat的使用

Android下junit单元测试 软件测试小知识: 根据测试是否知道源代码:黑盒测试:只关心程序执行的过程和结果白盒测试:根据源代码写测试方法或者测试用例. 根据测试的粒度: 方法测试:function test单元测试:unit test 集成测试:intergration test 根据测试的次数: 冒烟测试:smoke test(android 猴子) 压力测试:prssure testAndroid单元测试: 1.Android测试类要继承AndroidTestCase类 2.写测试方

《精通移动App测试实战:技术、工具和案例》一2.3 应用JUnit对Android项目进行单元测试

2.3 应用JUnit对Android项目进行单元测试 2.3.1 JUnit基于Android项目TestCase的应用 如果我们对基于Android系统项目开发有一定了解的话,相信一定能看出来,其核心代码是计算两个整数相加的函数.我们做单元测试当然也挑选其最核心的函数来进行测试.可以按照如下的步骤来创建一个基于Android项目的测试用例(TestCase). 第一步:选中"CalculatorOfTwoNum"项目下的"src"目录中的"com.yu

Android最佳Mock单元测试方案:Junit + Mockito + Powermock

本文旨在从实践出发,引导开发者在Android项目中进行Mock单元测试. 什么是单元测试 单元测试由一组独立的测试构成,每个测试针对软件中的一个单独的程序单元.单元测试并非检查程序单元之间是否能够合作良好,而是检查单个程序单元行为是否正确. 为什么要进行单元测试 在敏捷开发大行其道的今天,由于时间紧,任务重,过分依赖测试工程师以及下列原因,导致单元测试不被重视,在开发流程中处于一个可有可无的尴尬境地. 1. 浪费的时间太多 1. 软件开发人员不应参与单元测试 1. 我是很棒的程序员,不需要进行

在Android中进行单元测试遇到的问题

问题1.Cannot connect to VM  socket closed 在使用JUnit进行测试的时候,遇到这个问题.网上的解释是:使用Eclipse对Java代码进行调试,无论是远程JVM还是本地JVM都会进行Socket通讯.发生这样的错误是由于这些软件会修改winsock,还会监听和占用一些端口,Socket通讯不上造成的. 我通过cmd →ping localhost ,发现localhost指向::1,这是因为我的系统是win7 ,它支持IPv6的原因.而Eclipse需要lo

【黑马Android】(02)短信发送器/布局演示/android下单位/android下Junit/保存数据/android下权限/xml解析和序列化

短信发送器 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.itheima28.smssender" android:versionCode="1" android:versionName=&quo

简单谈谈android studio 的单元测试_Android

面对android studio Run 一次项目要等好几分钟的痛点,不得不研究一下android studio 的单元测试. 其实我的目的很简单,在不对视图进行操作的前提下,测试一些activity 的生命周期,或网络拉取数据的一些处理,比如解析 json 数据啊,做网络请求啊等等,也就是对 Model层的测试.这些不需要操作视图,但在没有单元测试环境下,比如我们网络请求一些数据,Log 打印看看是否请求成功,却又要 利用模拟器或真机Run 一次项目,花费好几分钟,这是不能容忍的. 于是乎,强

Android编程之单元测试实例分析_Android

本文实例讲述了Android编程之单元测试用法.分享给大家供大家参考,具体如下: 在实际开发中,开发android软件的过程需要不断地进行测试.使用Junint测试框架,是正规Android开发的必用技术,在Junint中可以得到组件,可以模拟发送事件和检测程序处理的正确性.单元测试是嵌入到项目中:也可以作为一个单独的项目争对某个具体项目进行测试. 第一步:首先在AndroidManifest.xml中加入下面红色代码: <manifest xmlns:android="http://sc

Android编程之单元测试实例分析

本文实例讲述了Android编程之单元测试用法.分享给大家供大家参考,具体如下: 在实际开发中,开发android软件的过程需要不断地进行测试.使用Junint测试框架,是正规Android开发的必用技术,在Junint中可以得到组件,可以模拟发送事件和检测程序处理的正确性.单元测试是嵌入到项目中:也可以作为一个单独的项目争对某个具体项目进行测试. 第一步:首先在AndroidManifest.xml中加入下面红色代码: <manifest xmlns:android="http://sc

简单谈谈android studio 的单元测试

面对android studio Run 一次项目要等好几分钟的痛点,不得不研究一下android studio 的单元测试. 其实我的目的很简单,在不对视图进行操作的前提下,测试一些activity 的生命周期,或网络拉取数据的一些处理,比如解析 json 数据啊,做网络请求啊等等,也就是对 Model层的测试.这些不需要操作视图,但在没有单元测试环境下,比如我们网络请求一些数据,Log 打印看看是否请求成功,却又要 利用模拟器或真机Run 一次项目,花费好几分钟,这是不能容忍的. 于是乎,强