前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓基础干货(二):安卓测试以及解析

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

作者头像
緣來
发布2018-09-18 17:53:51
8050
发布2018-09-18 17:53:51
举报
文章被收录于专栏:緣來來來

1.测试的相关概念

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

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

  1. 根据测试的粒度分类:

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

  1. 根据测试的暴力程度:

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. 写一个业务类,写一个业务方法:
代码语言:javascript
复制
public class CalcService {
    public static int add(int x,int y){ 
        return x+y;
    }
}

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

代码语言:javascript
复制
public class CalcServiceTest extends AndroidTestCase{

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

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

代码语言:javascript
复制
<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应用程序存储数据的方式:

代码语言:javascript
复制
1、保存到文件
2、SQLite数据库
3、内容提供者
4、sharedproferrences保存数据
5、网络

/data/data/应用包名/info.txt

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

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

  1. 创建一个文件,目录/data/data/<包名>/文件名
  2. 创建一个文件输出流,把数据写到文件上
  3. 关闭输出流。

代码:

代码语言:javascript
复制
//保存数据
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)读取文件中的数据,并显示到界面上

代码语言:javascript
复制
@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卡(重点)

代码语言:javascript
复制
//异常信息:
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卡上写数据
代码语言:javascript
复制
String data = "dsfdsae";

File file = new File(Environment.getExternalStorageDirectory(), "info.txt");

FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getBytes());

fos.close();
  1. 在清单文件中添加访问SD卡的权限
代码语言:javascript
复制
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

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

代码语言:javascript
复制
//获得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.文件的权限概念

代码语言:javascript
复制
文件的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保存数据
代码语言:javascript
复制
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();
    }
}
  1. 从SharedPreferences读取数据
代码语言:javascript
复制
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文件

代码语言:javascript
复制
//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格式的数据 (重要)

代码语言:javascript
复制
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;//把所有的频道的集合返回回去
        }
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.测试的相关概念
  • 2.单元测试
  • 3.Logcat日志工具的使用
  • 4.把数据存储到文件
  • 5.从文件中读取数据并显示到界面上
  • 6.存储到SD卡(重点)
  • 7.获取SD的大小及可用空间
  • 8.文件的权限概念
  • 9.SharedPreferences第二种存储方式(重点)
  • 10.使用序列化器生成一个xml文件
  • 11.使用pull解析xml格式的数据 (重要)
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档