安卓基础干货(二):安卓测试以及解析

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+"http://www.likecs.com/"+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("\n"); } //把解析出来的天气信息设置到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;//把所有的频道的集合返回回去 } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdwdf.html