一、简单测试概念
1.源代码
[1]黑盒:功能测试
[2]白盒:写测试代码
2. 粒度
[1]方法测试
[2]单元测试
- Android工程运行在Dalvik VM 中,所以写单纯的Java程序测试会报以下错误:
- 顺便搜索了Jvm与Dvm的区别(ps:能力有限,没看太懂):
- 测试类 extends AndroidTextCase - android.test
//需要配置AndroidManifest.xml
<application /application>:
<uses-library android:name = "android.test.runner"/>
out of <application /application>:
<instrumentation android:name = "android.test.InstrumentationTestRunner"
android:targetPackage = "//当前用的包:cn.dhcode.unit"
android:label = "Tests for My App"/>
//定义成Android测试类,运行"Android JUnit Test"
//快捷方式:新建测试工程:New Android TestProject -> 选择工程
//断言 assertEquals(8,result);
[3]集成测试(客户端与服务器)
[4]系统测试(JavaEEWeb)
3.
[1]压力测试(goole : adb shell -> monkey count)
[2]冒烟测试
二、LogCat
android.until.Log 类
//各级别颜色
//过滤器
三、简陋login登陆案例
1.需求
2.UI
垂直线性+相对布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名" />
<EditText
android:id="@+id/et_userpasswd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="@+id/cb_ischeck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住用户名密码" />
<Button
android:id="@+id/bn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="login"
android:text="登录"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</LinearLayout>
3.业务逻辑
[1]控件ID
EditText et_name = (EditText)findViewById(R.id.et_username);
EditText et_passwd= (EditText)findViewById(R.id.et_userpasswd);
CheckBox cb_ischeck = (CheckBox)findViewById(R.id.cb_ischeck);
[2]按钮点击事件
public void login(View v){
//记得前面的变成成员(全局)变量
String name = et_name.getText().toSring().trim();
String pwd = et_passwd.getText().toString().trim();//可换行
//TextUtils - android.text
if(TextUtils.isEmpty(name)||TextUtils.isEmpty(pwd)){
Toast.makeText(MainActivity.this,"用户名或密码不能为空",1).show();
}else{
//登陆逻辑
System.out.println("连接服务器进行登录,等到网络编程时完善");
}
}
//密码密文
android:password = "true"
[3]保存数据
//新建工具类内涵业务方法UserInfoUtils.java
public class UserinfoUtils{
public static boolean saveInfo(String username, String userpasswd){
try{
String result = username+"###"+userpasswd;
//创建File类指定数据存储位置
File file = new File("/data/data/cn.dhccode.login/info.txt");
//创建文件输出流
FileOutputStream fos = new FileOutputStream(file);
fos.write(result.getBytes());
fos.close();
return true;
}catch(Exception e){
//e.printStackTrance();
return false;
}
}
if(cb_ischeck.isChecked()){
boolean result = UserInfoUtils.saveInfo(name,pwd);
if(result){
Toast.makeText(MainActivity.this,"保存成功",1).show();
}else{
Toast.makeText(MainActivity.this,"保存失败",1).show();
}
}
[4]回显数据//BUG : 密码为#时。
//控件下面读取info.txt信息UserInfoUtils.readInfo();
Map<String,String> maps = UserInfoUtils.readInfo();
if(maps!= null){
//取出name和pwd
String name = maps.get("name");
String pwd = maps.get("pwd");
//把name和pwd显示到editText控件下
et_name.setText(name);
et_passwd.setText(pwd);
}
public static Map<String,String> readinfo(){
try{
Map<String,String> maps = new HashMap<String,String>();
File file = new File("/data/data/cn.dhcode.login/info.txt");
FileInputStream fis = new FileInputStream(file);
BufferedReader bur = new BufferedReader(new InputStreamReader(fis));
String content = bur.readline();//读取数据
//切割字符串 封装到map集合中
String[] splits = content.split("##");
String name = splits[0];
String pwd = splits[1];
//把name 和 pwd 放入map中
maps.put("name",name);
maps.put("pwd",pwd);
fis.close();
return maps;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
[5]上下文获取常见目录
//google建议不写死路径
public static boolean saveInfo(Context context,String username, String userpasswd){}
//获取路径
String path = context.getFilesDir().getPath();
File file = new File(path,"info.txt");
//存数据
boolean result = UserInfoUtils.saveInfo(MainActivity.this,name,pwd);
//读
String path = context.getFilesDir().getPath();
File file = new File(path,"info.txt");
Map<String,String> maps = UserInfoUtils.readInfo(MainActivity.this);
mode:
一句顶四句:
//[0]获取文件保存路径
//String path = context.getFileDir().getPath();
String result = username + “##” +pwd;
//[1]创建file类制定我们要把数据存储的位置
//File file = new File(“/data/data/com.dhcode.login/info.txt”);
//File file = new File(“path”,”info.txt”);
//[2]创建一个文件输出流
//FileOutputStream fos = new FileOutputStream(file);
//[3]通过上下文获取FileOutputStream
FileOutputStream fos = context.openFileOutputStream(“infoo.txt”,0);
fos.write(result.getBytes());
fos.close();
return true;
public static Map<String,String>readInfo(Context context){
try{
Map<String,String> maps = new HashMap<String,String>();
FileInputStream fis = context.openFileInput(“infoo.txt”);
BufferedReader bufr = new BufferedReader(new InputStreamReader(fis));
String content = bufr.readLine();//读取数据
ps:到了复习流的时候了!还有Map类。
[6]数据保存到SD卡
File file = new File("/mnt/sdcard/info.txt");
需要外部存储设备权限
死目录:
String sdPath = Environment.getExternalStorageDirectory().getPath();
File file = new File(sdPath,“abc.txt”);
//判断sd卡状态是否卸载
if(cb_ischeck.isChecked()){
//先判断sd卡状态是否可用
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
Toast.makeText(getApplicationContext(),”sd卡可用”,1).show();
//保存用户数据
boolean result = UserInfoutils.saveInfo(name,pwd);
if(result){
Toast.makeText(MainActivity.this,”保存成功”,1).show();
}else{
Toast.makeText(MainActivity.this,“保存失败”,1).show();
}
}else{
Toast.makeText(getApplicationContext(),”sd卡不可用~”,1).show();
}
}
[7]获取sd卡总大小和可用空间
//找控件
TextView tv_total_size = (TextView)findViewById(R.id.TextView1);
TextView tv_usable_size = (TextView)findViewById(R.id.textView2);
//获取sd卡总大小和可用空间
File file = Environment.getExternalStorageDirectory();
long totalSpace = file.getTotalSpace();
long usableSpace = file.getUsableSpace();
//转换数据格式
String formatTotalSpace = Formatter.formatFileSize(this,totalSpace);
String formatUsableSpace = Formatter.formatFileSize(this,usableSpace);
//展示
tv_total_size.setText(“总大小” + formatTotalSpace);
tv_useable_size.setText(“可用的”+formatuseableSpace);
[8]文件权限
//点击按钮使用MODE_APPEND模式 生成一个append格式的文件
public void click2(){
try{
FileOutputStream fos = open FileOutput(“append.txt”,MODE_APPEND);//MODE_PRIVATE MODE_WORLD_WRITEABLE. MODE_WORLD_READABLE格式
fos.write(“append”.getBytes());
fos.close();
}catch(Exception e){
e.printStackTrance();
}
}
读取一下read模式文件
try{
File file = new File(“/data/data/com.dhcode.pri/files/read.txt”);
FileInputStream fis = new FileInputStream(file);
BufferedReader bur = new BufferedReader(new InputStreamReader(fis));
String content = bur.readLine();
System.out.println(“content:”+content);
}catch(Exception e){
e.printStackTrace();
}
修改文件权限:Linux :adb shell->cd 所在目录->chmod 777 private.txt. //chmod 660 private.txt
[9]SharedPreferences接口介绍(可保存数据并解决了上面的文件输入输出流bug)
存数据
if(cb_ischeck.isChecked){
//拿到sp实例
/*
*name 帮助生成xml文件
*mode 模式
*/
SharedPreferences sp = getSharedPreferences(“文件名字”,0);
//获取sp编辑器
Editor edit = sp.edit();
edit.putString(“name”,name);
edit.putString(“passwd”,pwd);
//把edit提交
edit.commit();
}
取数据
//先初始化sp实例
sp = getSharedPreferences(“文件名字”,0);
//在xml文件中取出数据显示到edittext控件上
String name = sp.getString(“name”,””);
String pwd = sp.getString(“passwd”,””);
et_name.setText(name);
et_passwd.setText(pwd);
//tips: //TODO. -->代码标记行
四、xml文件
[1]xml序列化
生成XML的第一种方法手动拼装
//Sms.java Java Bean
public class Sms{
private String address;
private String body;
private String date;
}
//main.java 1.初始化要备份的短信数据
List<Sms> smsLists = new ArrayList<Sms>();//
for (int i = 0;i<10;i++){//手动组拼假数据
Sms sms = new Sms();
sms.setAddress(“1008”+i);
sms.setBody(“nihao”+i);
sms.setDate(“201”+i);
//[2]把sms对象加入集合中
smsLists.add(sms);
}
//点击按钮通过StringBuffer的方式手动拼装一个xml文件
Public void click(View v)
{
StringBuffer sb = new StringBuffer();
//xml文件头
sb.append(“<?xml version=\”1.0\” encoding = \”utf-8\”?>”);
//xml根节点
sb.append(“<smss>”);
//sms节点
for(Sms sms:smsLists){
sb.append(“<sms>”);
//开始拼接address节点
sb.append(“<address>”);
sb.append(sms.getAddress());
sb.append(“</address>”);
sb.append(“<body>”);
sb.append(“sms.getBody”);
sb.append(“</body>”);
sb.append(“<date>”);
sb.append(“sms.getDate”);
sb.append(“</date>”);
sb.append(“</sms>”);
}
sb.append(“</smss>”);
//把数据保存到sd卡中
try {
File file = new File(Environment.getExternalStorageDirectpry().getPath(),”text.xml”);
FileOutputStream fos = new FileOutputStream(“file”);
fos.write(sb.toString().getBytes());
fos.close();
}catch(Exception e){e.printStackTrance}
}
//记得加权限
生成XML的第二种方法
//获取XmlSerializer 类的实例 通过XML这个工具类获取
XmlSerializer serializer = Xml.newSerializer();
//设置xmlserializer序列化器参数
File file = new File(Environment.getExternalStorageDirectory().getPath(),”smsbackup.xml”);
FileOutputStream fos = new FileOutputStream(file);
Serializer.setOutput(fos,“utf-8”);
//xml文档开头
serializer.startDocument(“utf-8”,true);
//xml根节点
serializer.startTag(null,“smss”);
//循环sms节点
for(Sms sms:smsLists){
serializer.startTag(null,“sms”);
serializer.startTag(null,“address”);
serializer.text(sms.getAddress());
serializer.endTag(null,”address”);
//………
serializer.endTag(null,”sms”);
}
serializer.endTag(null,”smss”);
serializer.endDocument();
fos.close();
[2]xml解析
xml的数据来源 ->服务器