程序测试
好的应用程序不是写出来的,是测出来了
测试分类
- 根据是否知道应用程序的源代码
- 黑盒测试(也称用户测试) 不知道程序的源代码,但是知道程序的功能,根据输入测试输出
- 白盒测试(也称程序员测试) 知道程序的源代码,写一写测试逻辑跑这个程序的代码
- 基于是否执行被测试程序
- 静态测试
- 动态测试
- 根据测试的粒度(精细程度)
- 方法测试 function test
- 单元测试 unit test
- 集成测试 intergration test
- 系统测试 system test
- 根据测试的暴力程度
- 压力测试 pressure test 单位时间内的频繁测试
- 冒烟测试 smoke test 长时间的重复测试
android下开发的代码写junit测试用例和普通pc机下的java代码不一样
要把应用程序部署到模拟器或者真实的手机去运行.
Android中的测试
应用层的测试
测试常规的功能是否完善, 不会出现致命的bug
Google 的CTS的测试
任何一款android手机,在上市前都需要通过谷歌的 cts 测试, 如果没有通过 。
Cts(compatibility test suit )
Framework的测试
包括:
1. Mediaframework ( 多媒体框架。包含stagefright , camera (指相机系统,不是单单的指照相机,很复杂)framwork , NFC ),
2. Wifi,
3. GPS,
4. sensor
Android下junit测试代码的写法
Eclipse下的测试
- 写一个业务方法
- 测试这个业务方法,写一个类继承AndroidTestCase
- 编写测试的代码
assertEquals(期待的结果,真实的结果) - 配置androidmenifest.xml 清单文件
<!-- 指定测试框架运行的指令集,告诉模拟器测试我们的应用程序,指定包名,其中android:name取值是固定的,表示测试使用的指令集。而targetPackage表示测试目标,就是当前工程的包名 -->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.itheima.junit"
></instrumentation>
5.在application节点里面配置
<!-- 引入测试框架的jar包 -->
<uses-library android:name="android.test.runner"/>
6.运行测试代码,对着方法名点击右键,run as android junit test
7.根据红条还是绿条判断测试结果
Android Studio下的测试:
写在全面的话
下面是对与Android Studio测试相关内容的接受如果不感兴趣可一直看相关内容
笔者使用的是当前最新的Android Studio 2.0 Beta 4 和1.5也存在者差异
在网上看到自AS1.5开始,当项目新建时会生成两个默认的测试目录: test, androidTest,其中 test目录为在本机执行单元测试代码的目录, androidTest为在Android设备上执行单元测试代码的目录。
- AS2.0在Android试图下都会显示,而AS1.5需要切换到Project下
- Build Variants二者存在差异
在AS 1.5中两类测试只能选择其中一个进行运行,需要配置Build Variants,但是AS2.0却不用去做出切换和配置,就是说,你想运行哪类测试,就可以运行哪类!!
AS2.0
AS1.5
AS2.0直接右键
好的我们步入正题
androidTest
Android的组成部分的测试
test
如果你要进行的单元测试与Android没有任何依赖,或者只有简单的依赖的话,这个时候你应该在本地开发机器上测试。这种测试方法效率高,因为它可以帮助你避免每次把测试运行时的目标应用程序和单元测试代码加载到真实设备或模拟器带来的额外开销。因此,执行时间为运行单元测试大大降低。
- 创建单元测试
- Android Studio提供了一个快速创建测试类的方法。只需在编辑器内右键点击<需要测试类>的声明,选择Go to > Test,然后”Create a new test…”
- 在打开的对话窗口中,选择JUnit4和”setUp/@Before”,同时为所有的<测试类方法>生成测试方法。
- 运行单元测试
终于到运行测试的时候了!右键点击<需要进行测试>类,选择Run > <测试类>Test。(例如:PersonTest)
结果:
下面的文章给了我很大帮助:
http://www.mobibrw.com/p=2634
http://www.jianshu.com/p/03118c11c199
输入输出
从文件里面读取数据
把数据写到文件
输入输出的应用场景
qq登陆保存用户名和密码
注意: android下应用程序的路径和javase不同,应用程序的数据要保存自己的文件夹里面getFileDir(); 获取自己的文件夹 /data/data/包名/files getCacheDir(); /data/data/包名/cache
谷歌给我们提供了两种应用程序的目录,files目录存放重要的应用程序数据.手机不会自动清理files目录的文件
cache目录是存放临时的不重要的数据.这个目录有特定,当手机内存空间不足的时候会自动清理cache目录的文件
手机存储空间的划分
- 手机内部存储 Environment.getDataDirectory()
file目录 cache目录
容量有限,较小,价格比较贵,存储访问速度快
创建的文件在手机内部存储空间,默认的权限全部都是私有的.
只有自己的应用程序可以访问,
别的应用程序不可以访问.
为什么不需要声明权限?
- 手机外部存储 Environment.getExternalStorageDirectory()
sd卡
容量大,可以更换,价格便宜,32G 不到200块
读写声明权限
文件目录 : /sdcard —>软连接 —->/mnt/sdcar/(来自Linux系统的分配方式)
如果想创建别的权限的文件
openFileOutput(“文件名”, “访问模式”);
MODE_WORLD_READABLE 全局可读,别的应用程序可以读这个文件
MODE_WORLD_WRITEABLE 全局可写,别的应用程序可以写这个文件
MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE 全局可读可写,别的应用程序可以自由的访问这个文件
【重点】linux&android中文件的权限
linux下的文件权限
因为Android的底层是Linux系统,所以Linux的权限是什么样的Android文件的权限就是什么。
例如:
- rw- rw- -w-
- :代表是一个文件
rw- :当前的应用【自己具有的权限】
rw- :当前的应用【所在组的权限】
-w-:当前应有【 所在的组之外的部分 具有的权限】
那么,有人会问:什么是组呢??
Linux&Android下是的【组】:
说到【组】其实就是Linux系统下的权限管理策略
在Linux下每当新建一个用户(Android下 一个应有就是一个 用户)就会新建一个组,每个组都有一定的权限。
假设:Linux有两个用户:A和B,则系统默认为他们建一个与用户名称相对应的组。每个组都拥有自己的文件控制权限。A就拥有A组的权限,B就拥有B组的权限。
A —->A组{ C }
B —->B组{ }
C —->C组{ }
假如再新建一个用户 C,并且将C加入到A的组中,那么 C 就拥有了A的权限同时还拥有自己的权限所以
A组的权限 == C 所在组的权限
C组的权限 == C 自身的权限
B 组的权限 == C 所在组 之外部分的权限
结合以上我们知道:
- rw- rw- -w-
即:
1位:0代表文件,d代表文件夹
2·3·4位:所在组的权限
5·6·7位:自身的权限
8·9·10位:所在的组之外的部分 具有的权限
其中的r,w,x 有代表什么呢??
权限符号:
r = 4 代表读权限–> read
w = 2 代表写权限–> write
x = 1 代表执行权限–> execute
他们可以累加,所以:- rw- rw- -w-
就可以表示为: 661
Linux下更改权限:
chmod : 代表 change mode 修改模式
chmod 777
Context 是什么
上下文 : 程序运行的一个依赖的环境. 必须有这个环境,才可以方便的执行代码.
应用程序运行的全局的环境.帮助类.
共享参数 SharedPreference 方式存储
SharedPerference是Android提供的一个独有的保存数据的机制。以XML形式存储
创建内容
/**
* SharedPreference
* getSharedPreferences("config",Context.MODE_PRIVATE)
* config 文件将会生成在 应用的文件夹下 --->是一个XML文件
* 一般情况下,应用自己的数据 只有 自己可以去读,所以通常会写 Context.MODE_PRIVATE == 0
*/
try {
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
//拿到sp的编辑器,使用键值对的方式写入数据
SharedPreferences.Editor editor = sp.edit();
editor.putString("private", "private file by SharedPreferences");
//将数据提交,到private数据中
editor.commit();
Toast.makeText(FileAccessPermission.this, "创建私有文件成功",
Toast.LENGTH_SHORT).show();
btnShowPrivateFileContentSp.setEnabled(true);
btnShowPrivateFileContentSp.setFocusable(true);
btnShowPrivateFileContentSp.setClickable(true);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(FileAccessPermission.this, "创建私有文件成功 失败",
Toast.LENGTH_SHORT).show();
}
读取内容
//系统会自动检查,是否存在config文件,有过没有就创建。
sp = getSharedPreferences("config", 0);
//如果找到值 就返回,如果没有找到,就返回默认值
content = sp.getString("private", "");
txtShowFileContentFilePermission.setText(content);
保存数据到
1. 声明sp
private SharedPreferences sp;
2. 初始化sp
sp = this.getSharedPreferences(“config”, MODE_PRIVATE);
3. 使用sp
Editor editor = sp.edit();
editor.putString(“qq”, qq);
editor.putString(“password”, password);
//一定不要忘记 提交数据
editor.commit();//提交数据. 类似关闭流,事务
4. 读取sp
sp.getString(“qq”, “”);
xml的生成
- 采用组拼字符串生成xml文件.
组拼字符串 StringBuilder, StringBuffer 注意特殊字符的转义
- 利用android序列化(生成)xml文件的api
1. XmlSerializer serializer = Xml.newSerializer();
2. serializer.setOutput("输出流", "文件编码");
3. 写文件的头
serializer.startDocument("utf-8", true);
serializer.endDocument();//写文件的末尾
4. 写节点
serializer.startTag(null, "info");
serializer.endTag(null, "info");
5. 写属性
serializer.attribute(null, "id", id);
6. 写节点里面的文本
serializer.text("文本");
xml的解析
- DOM解析
树状的xml结构
- Dom4j
- SAX
基于事件解析,自上而下的解析
- Pull解析
类似sax解析,不过写起来更加的简单,容易理解,内存开销小,速度快
pull解析
- 声明一个解析器
XmlPullParser parser = Xml.newPullParser(); - 设置解析的数据
parser.setInput(“哪个文件的输入流”,”文件编码”); - 获取解析器发现的事件的类型
parser.getEventType(); //第一个事件一定是文档的开头 - 不停的解析所有的节点
while(type!=XmlPullParser.END_DOCUMENT){
type = parser.next();//只要不解析到文档的末尾就不停的解析下一个节点
} - 在解析过程中把我们关心的数据获取出来
parser.getName() //得到当前节点的名称
parser.nextText(); 文本 //取出两个节点之间的文本
parser.getAttributeValue(namespace, 属性名称) 获取某个属性的值 - 得到数据,完成界面的展现
断点调试应用程序
- 双击在代码的左边打一个断点
- 右键,debug as android application
- 右键 watch 查看数据
- watch 一段代码
- 清空原来的调试断点