一、单元测试的引入:
如果只是普通的一个小程序,编写测试是有些多此一举,但是当项目比较庞大的时候,一般都应该去编写单元测试。JUnit测试是白盒测试,即主要是程序员自己对开发的方法进行功能性测试。JUnit是一套框架,Android中也沿用了这一套框架。
在Android中使用JUnit测试大致分为如下几个步骤:
二、步骤详解:
(1)配置清单文件:
新建Android工程文件,命名为m05_SharedPerencesTest,
首先在AndroidManifest.xml添加一个Instrumentation:
指定Instrumentation的name与TargetPackage:
Name: android.test.InstrumentationTestRunner
Target package: com.example.m05_sharedperencestest
然后,保存。
紧接着在
完成后,AndroidManifest.xml代码如下:
上方11至14行以及21行是我们所添加的代码。请将第13行改为自己的包名。
编写一个类,我们需要做的是在里面实现记住密码的功能:
通过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 map) {
boolean flag = false;
SharedPreferences preferences = context.getSharedPreferences(fileName,
Context.MODE_PRIVATE);
Editor editor = preferences.edit();
for (Map.Entry 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代码如下:
package com.example.m05_sharedpreferencestest;
import java.util.Map;
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;
}
//方法:通过SharedPreferences保存用户输入的用户名、密码(各种数据类型)
public boolean saveSharePreference(String fileName, Map map) {
boolean flag = false;
SharedPreferences preferences = context.getSharedPreferences(fileName,
Context.MODE_PRIVATE);
Editor editor = preferences.edit();
for (Map.Entry 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;
}
//方法:数据存储之后,然后读出来
public Map getSharePreference(String fileName) {
Map map = null;
SharedPreferences preferences = context.getSharedPreferences(fileName,
Context.MODE_PRIVATE);
map = preferences.getAll();
return map;
}
}
MyTest.java代码如下:
package com.example.m05_sharedpreferencestest;
import java.util.HashMap;
import java.util.Map;
import android.test.AndroidTestCase;
import android.util.Log;
public class Mytest extends AndroidTestCase {
private final String TAG = "Mytest";
public Mytest() {
// TODO Auto-generated constructor stub
}
public void save(){
LoginService loginService = new LoginService(getContext());
boolean flag = loginService.saveLoginMsg("smyhvae", "smyh");
//如果数据保存成功,saveLoginMsg()方法将返回true值。
Log.d(TAG, ""+flag);
}
public void save2() {
LoginService service = new LoginService(getContext());
Map map = new HashMap();
map.put("name", "jack");
map.put("age", 23);
map.put("salary", 3000.0f);
map.put("id", 1010010101l);
map.put("isManager", true);
boolean flag = service.saveSharePreference("msg", map);
Log.i(TAG, "--->>" + flag);
}
public void read() {
LoginService service = new LoginService(getContext());
Map map = service.getSharePreference("msg");
Log.i(TAG, "--->" + map.get("name"));
Log.i(TAG, "--->" + map.get("age"));
Log.i(TAG, "--->" + map.get("salary"));
Log.i(TAG, "--->" + map.get("id"));
Log.i(TAG, "--->" + map.get("isManager"));
}
}
如果执行read()方法的单元测试,后台输出如下:
三、常见测试方法:
黑盒测试: 是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。
白盒测试: 又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。
单元测试: 又称模块测试,是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。
功能测试: 根据产品特性、操作描述和用户方案,测试一个产品的特性和可操作行为以确定它们满足设计需求。
压力测试: 主体向被观察者布置一定量任务和作业,借以观察个体完成任务的行为。
集成测试: 是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口
备注:黑盒测试,不看代码结构,从用户的角度测试功能,例如玩某一款游戏来测试。白盒测试:通过代码测试功能。
软件测试可以从不同的角度加以分类:
基于是否关注软件结构与算法:
基于是否执行被测试软件:
基于测试的不同阶段:
此外还有压力测试等。
如果理解不便,下面是更简单的一篇基于Eclipse平台的解释(单元测试):
1) 掌握单元测试的方法;
2) 学习 JUnit 测试原理及框架;
3)掌握在 Eclipse 环境中加载 JUnit 及 JUnit 测试方法和过程。
Eclipse 集成JUnit,可以非常方便地编写TestCase。Eclipse自带了一个JUnit 插件,不用安装就可以在项目中测试相关的类,并且可以调试测试用例和被测类。下面以实例说明,如 何建立一个基于JUnit4 的测试项目,对一个类当中的多个方法进行单元测试
public class claculator {
private static int result; //静态变量,用于存储运行结果
public void add(int n) { result = result+n; }
public void substract(int n)
{result = result-1; //有意设置的Bug,应该是result=result-n}
public void multiply(int n) {}
public void divide(int n) { result = result/n; }
public void square(int n) { result = n*n; }
public void squareRoot(int n) { //求平方根
for( ; ; ) //Bug:死循环
{}
}
public void clear() {
result = 0;
}
public int getResult() {
// TODO Auto-generated method stub
return result;
}
}
---------------------
参考文章:https://blog.csdn.net/fanyuwgy/article/details/77986521
参考文章:https://www.cnblogs.com/smyhvae/p/4020443.html
---------------------