zoukankan      html  css  js  c++  java
  • 安卓基础干货(二):安卓测试以及解析

    1.测试的相关概念

    1、根据是否知道源代码分类:

    黑盒测试: a - b - c  边值测试
    白盒测试: 根据源代码写测试方法 或者 测试用例;
    

    2、根据测试的粒度分类:

    方法测试:写完一个方法后就测试
    单元测试:测试一个能够独立运行的业务逻辑单元;
    集成测试:整体测试项目 联调
    系统测试:对整个系统进行测试
    

    3、根据测试的暴力程度:

    1、冒烟测试:高频次的点击软件
    2、压力测试:使用测试工具:LoadRunner、Jmeter
    

    2.单元测试

    Junit

    01_Junit单元测试 does not specify a android.test.InstrumentationTestRunner instrumentation or does not declare uses-library android.test.runner in its AndroidManifest.xml
    

    单元测试的步骤:

    1、写一个业务类,写一个业务方法:

    public class CalcService {
    
    public static int add(int x,int y){
    	
    	return x+y;
    }
    

    }

    2、写一个测试类,写一个测试方法,用来测试业务方法

    public class CalcServiceTest extends AndroidTestCase{
    
    public void testAdd(){
    	int result = CalcService.add(4, 5);
    	assertEquals(9, result);
    	}
    
    }
    

    3、在清单文件中添加测试需要的包

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima.junit"
    android:versionCode="1"
    android:versionName="1.0" >
    
    
    <!-- 添加指令集,添加到manifest节点的里面,指令集会把应用程序部署到模拟器上运行 -->
    
    <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.itheima.junit"></instrumentation>
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    
        <!-- 添加JUnit的测试包 ,添加到application节点的里面-->
    
        <uses-library android:name="android.test.runner"/>
        
        ....
    </application>
    
    </manifest>
    

    3.Logcat日志工具的使用

    日志的等级:
    error:最高等级,错误信息,红色
    warn:比较高,警告信息,橙色
    debug:较高,调试信息,蓝色
    info:一般,一般信息,绿色
    verbose:一般,所有信息,黑色

    4.把数据存储到文件

    Android应用程序存储数据的方式:

    1、保存到文件
    2、SQLite数据库
    3、内容提供者
    4、sharedproferrences保存数据
    5、网络
    
    /data/data/应用包名/info.txt
    

    5.从文件中读取数据并显示到界面上

    (1)把文件保存到当前应用程序的目录下的步骤:

    1、创建一个文件,目录/data/data/<包名>/文件名
    2、创建一个文件输出流,把数据写到文件上
    3、关闭输出流。
    代码:
                //保存数据
    			File file = new File("/data/data/com.itheima.login/info.txt");
    			FileOutputStream fos = new FileOutputStream(file);
    			String info = qq + "##"+ pwd;
    			fos.write(info.getBytes());
    			
    			fos.close();
    			Toast.makeText(this, "保存数据成功", 0).show();
    

    (2)读取文件中的数据,并显示到界面上

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        
        et_qq = (EditText) findViewById(R.id.et_qq);
        
        et_pwd = (EditText) findViewById(R.id.et_pwd);
        
        cb = (CheckBox) findViewById(R.id.cb);
        
        //读取文件中的数据,并显示到界面上
        Map<String,String> map = readInfo(this);
        if(map != null){
        	et_qq.setText(map.get("qq"));
        	
        	et_pwd.setText(map.get("pwd"));
        }
        
    }
    
     /**
     * 读取文件中的数据
     * @param ctx
     * @return
     */
    public Map<String,String> readInfo(Context ctx){
    	String qq = "";
    	String pwd = "";
    	Map<String,String> map = new HashMap<String,String>();
    	try {
    		File file = new File("/data/data/com.itheima.login/files/info.txt");
    		FileReader fr = new FileReader(file);
    		BufferedReader br = new BufferedReader(fr);
    		String info = br.readLine();
    		
    		String[] array = info.split("##");
    		qq = array[0];
    		pwd = array[1];
    		
    		map.put("qq", qq);
    
    		map.put("pwd", pwd);
    		return map;
    		
    	} catch (Exception e) {
    		e.printStackTrace();
    		return null;
    	}
    	
    	
    }
    

    6.存储到SD卡(重点)

    异常信息:
    09-21 23:25:32.068: W/System.err(24718): java.io.FileNotFoundException: /storage/sdcard/info.txt: open failed: EACCES (Permission denied)
    

    步骤:

    1、	在SD卡上创建一个文件,
    
    2、创建一个输出流往sd卡上写数据
    String data = "dsfdsae";
    		
    		File file = new File(Environment.getExternalStorageDirectory(), "info.txt");
    		
    		FileOutputStream fos = new FileOutputStream(file);
    		fos.write(data.getBytes());
    		 
    		fos.close();
    
    3、在清单文件中添加访问SD卡的权限
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    7.获取SD的大小及可用空间

    //获得sd卡的目录对象
    	File file = Environment.getExternalStorageDirectory();
    	
    	//获得sd卡总空间的大小
    	long total =  file.getTotalSpace();
    	
    	//转换数据大小的数据单位
    	String totalSize = Formatter.formatFileSize(this, total);
    	//获得sd卡剩余空间的大小
    	long usable = file.getUsableSpace();
    	
    	String usableSize = Formatter.formatFileSize(this, usable);
    	
    	tv.setText(usableSize+"/"+totalSize);
    

    8.文件的权限概念

    文件的4种操作模式:
    Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND
    
    Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
    Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。
    
    MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
    如果希望文件被其他应用读和写,可以传入: 
      openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE +             Context.MODE_WORLD_WRITEABLE);
    
    android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。
    

    9.SharedPreferences第二种存储方式(重点)

     主要用于
    
    (1)往SharedPreferences保存数据
    	
     public void save(View v){
    	
    	String data = et.getText().toString().trim();
    	if(TextUtils.isEmpty(data)){
    		Toast.makeText(this, "请输入数据", 0).show();
    		return;
    	}else{
    		
    		//得到一个SharedPreferences
    		SharedPreferences sp = this.getSharedPreferences("info", Context.MODE_PRIVATE);
    		//SharedPreferences提供了一个编辑器,帮助我们保存数据
    		Editor editor = sp.edit();
    		
    		editor.putString("data", data);
    		
    		//把数据保存到SharedPreferences中
    		editor.commit();
    
    	}
    }
    
    (2)从SharedPreferences读取数据
    public String readData(){
    	
    
    	String data;
    	try {
    		//得到一个SharedPreferences
    		SharedPreferences sp = this.getSharedPreferences("info", Context.MODE_PRIVATE); 
    		//根据参数名称得到数据
    		data = sp.getString("data", null);
    	} catch (Exception e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    		data = "";
    	}
    	
    	return data;
    	
    }
    

    10.使用序列化器生成一个xml文件

    //1,初始化一个xml文件的序列化器
    		XmlSerializer serializer = Xml.newSerializer();
    		//2.初始化序列器参数
    		File file = new File(Environment.getExternalStorageDirectory(),"backup.xml");
    		FileOutputStream fos = new FileOutputStream(file);
    		serializer.setOutput(fos, "UTF-8");
    		//3.开始写xml文件.
    		serializer.startDocument("UTF-8", true);
    		serializer.startTag(null, "smss");
    		for(SmsInfo info : smsInfos){
               //开始写sms节点
    			serializer.startTag(null, "sms");
    			//开始写body节点
    			serializer.startTag(null, "body");
    			serializer.text(info.getBody());
                //body节点结束
    			serializer.endTag(null, "body"); 
    			
    			//开始写address节点
    			serializer.startTag(null, "address");
    			serializer.text(info.getAddress());
    			serializer.endTag(null, "address");
    			
                //开始写data节点
    			serializer.startTag(null, "date");
    			serializer.text(info.getDate()+"");
    			serializer.endTag(null, "date");
    			// sms节点结束
    			serializer.endTag(null, "sms");
    		}
    		//smss根节点结束
    		serializer.endTag(null, "smss");
            //xml 结束
    		serializer.endDocument();
    		fos.close();
    		
    		Toast.makeText(this, "备份短信成功", 0).show();
    	} catch (Exception e) {
    		e.printStackTrace();
    		Toast.makeText(this, "备份短信失败", 0).show();
    	}
    

    11.使用pull解析xml格式的数据 (重要)

    public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
       // 设置activity显示的布局
    	setContentView(R.layout.activity_main);
    	TextView tv_info = (TextView) findViewById(R.id.tv_info);
    	StringBuilder sb = new StringBuilder();
    	try {
            //获取我们解析出来的天气信息
    		List<Channel> channels = WeatherService.getAllWeatherInfos(getClass().getClassLoader().getResourceAsStream("weather.xml"));
    		for(Channel channel : channels){
    			sb.append(channel.toString());
    			sb.append("
    ");
    		}
            //把解析出来的天气信息设置到textview上
    		tv_info.setText(sb.toString());
    	
    	} catch (Exception e) {
    		e.printStackTrace();
    		Toast.makeText(this, "解析天气信息失败", 0).show();
    	}
    	
    }
    
    }
    

      public class WeatherService {
    /**
     * 解析服务器返回的数据 获取天气信息
     * @param is 服务器返回的包含天气信息的流 (xml)
     * @return
     */
    public static List<Channel> getAllWeatherInfos(InputStream is) throws Exception{
    	List<Channel> channels = null;
    	Channel channel = null;
    	//1.获取xml解析器
    	XmlPullParser parser = Xml.newPullParser();
    	//2.设置xml解析器的参数
    	parser.setInput(is, "utf-8");
    	//3.开始解析xml文件.
    	
    	int type = parser.getEventType();// 获取当前的事件的类型 
    	while (type!=XmlPullParser.END_DOCUMENT){ //需要让pull解析器解析到文件的末尾
    		switch (type) {
    		case XmlPullParser.START_TAG:
    			if("weather".equals(parser.getName())){//总的开始节点
    				channels = new ArrayList<Channel>(); //初始化集合
    			}else if("channel".equals(parser.getName())){//某个城市的信息开始了.
    				channel = new Channel();
                    //获取到id的属性值
    				String id = parser.getAttributeValue(0);
    				channel.setId(Integer.parseInt(id));
                    //解析city节点
    			}else if("city".equals(parser.getName())){
    				String city = parser.nextText();
    				channel.setCity(city);
                    //解析温度节点
    			}else if("temp".equals(parser.getName())){
    				String temp = parser.nextText();
    				channel.setTemp(temp);
                    //解析风力节点
    			}else if("wind".equals(parser.getName())){
    				String wind = parser.nextText();
    				channel.setWind(wind);
                     //解析pm250节点
    			}else if("pm250".equals(parser.getName())){
    				String pm250 = parser.nextText();
    				channel.setPm250(Integer.parseInt(pm250));
    			}
    			break;
            //判断xml的结束节点
    		case XmlPullParser.END_TAG:
    			if("channel".equals(parser.getName())){
                    //把解析的内容加入到集合中
    				channels.add(channel);
    				channel = null;
    			}
    			break;
    		}
    		
    		type = parser.next();
    	}
    	
    	is.close();
    	return channels;//把所有的频道的集合返回回去
     }
    }
  • 相关阅读:
    Redis 缓存 + Spring 的集成示例
    ETCD相关介绍--整体概念及原理方面
    SpringCloud微框架系列整体模块梳理
    win7如何修改磁盘驱动器号,怎么修改磁盘名称
    Android ListView中子控件的状态保存以及点击子控件改变子控件状态
    Android 自己动手写ListView学习其原理 3 ItemClick,ItemLongClick,View复用
    点击itemView选中checkbox
    Android-RecyclerView-Item点击事件设置
    onItemClickListener监听的整个item的点击。如何只监听那个framelayout的点击 onItemClickListener监听的整个item的点击。如何只监听那个framelayout的点击
    listView中setOnItemClickListener和getSelectedItemPosition()取不到position问题
  • 原文地址:https://www.cnblogs.com/fanchcho/p/9233851.html
Copyright © 2011-2022 走看看