Android单元测试框架 - 吴明
- Android单元测试
- 在Android项目中,单元测试的对象是组件状态、控件行为、界面元素和自定义函数。不推荐对每个函数进行一对一的测试,像onStart()、onDestroy()这些周期函数并不需要全部覆盖到。
- 框架比较
- JUnit
- 原生单元测试
- 不能让Activity执行到resume的状态
- @王进已讲
- AndroidTest
- 运行在Android环境
- Instrumentation
- 运行在模拟器上
- Robotium
- 类似于Selenium的测试框架
- 运行在模拟器上
- 通过对模拟器的操作或者mock,来触发函数调用,进而对其结果进行验证
- Robolectric+Mock(Mockito)
- 运行在JVM上速度快
- Jenkins周期性执行
- 无需准备Android环境
- 实现了Android中对XML的解析,模拟了View,Layout,以及资源的加载
- 一些测试对象依赖度较高而需要解除依赖的场景(如网络)使用Mock框架
- JUnit
-
Android Studio配置
build.gradle添加库
1
testCompile "org.robolectric:robolectric:3.0"
Build Variants设置
- Linux和Mac平台的需要配置下才能运行:在Android Studio中run边上有一个app选择,这里选择”Edit Configurations” 出现编辑界面
在左边中新建JUnit,Default->JUnit - 测试代码
- 中间出现问题
- Android SDK目前只支持到22,5.1
单元测试的目标函数主要有三种:
- 有明确的返回值,如上图的dosomething(Boolean param),做单元测试时,只需调用这个函数,然后验证函数的返回值是否符合预期结果。
- 这个函数只改变其对象内部的一些属性或者状态,函数本身没有返回值,就验证它所改变的属性和状态。
- 一些函数没有返回值,也没有直接改变哪个值的状态,这就需要验证其行为,比如点击事件。
- 既没有返回值,也没有改变状态,又没有触发行为的函数是不可测试的,在项目中不应该存在。当存在同时具备上述多种特性时,本文建议采用多个case来真对每一种特性逐一验证,或者采用一个case,逐一执行目标函数并验证其影响。
- 构造用例的原则是测试用例与函数一对一,实现条件覆盖与路径覆盖。Java单元测试中,良好的单元测试是需要保证所有函数执行正确的,即所有边界条件都验证过,一个用例只测一个函数,便于维护。在Android单元测试中,并不要求对所有函数都覆盖到,像Android SDK中的函数回调则不用测试。
测试用例
组件
Activity测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@Test
public void testLifecycle() {
ActivityController<MainActivity> activityController = Robolectric.buildActivity(MainActivity.class).create().start();
Activity activity = activityController.get();
Button action_next = (Button) activity.findViewById(R.id.next);
Assert.assertEquals("next", action_next.getText().toString());
// error
// Assert.assertEquals("testLifecycle", action_next.getText().toString());
}
````
- Service
- BroadcastReceiver
- Fragment
- 控件行为
- 跳转
- 界面元素
- Toast@Test
public void testToast() {
Button action_toast = (Button) mActivity.findViewById(R.id.action_toast);
action_toast.performClick();
Assert.assertEquals(“hello”, ShadowToast.getTextOfLatestToast());
}1
2- Dialog
- UI控件@Test
public void testStartEndActivity() {
Button action_next = (Button) mActivity.findViewById(R.id.next);
action_next.performClick();Intent intent = new Intent(mActivity, EndActivity.class);
Intent actionIntent = ShadowApplication.getInstance().getNextStartedActivity();
Assert.assertEquals(intent, actionIntent);
}1
- 自定义函数 - 网络请求 - assertJ-android断言库 - 资料 - [参考1](https://hkliya.gitbooks.io/unit-test-android-with-robolectric/content/0-introduction.html) - [美团Android单元测试](http://tech.meituan.com/Android_unit_test.html) - [测试用例](http://www.jianshu.com/p/9d988a2f8ff7) ## 无主题 - 陈奎 ###NodeJS 安装 - 到 [nodejs 下载](https://nodejs.org/download/release/) 下载 `node-v5.9.0-linux-x64.tar.gz`,上传到 linux 服务器 `/usr/local/nodejs` 目录; - 在 nodejs 目录执行
tar zxvf node-v5.9.0-linux-x64.tar.gz1
解压,进入解压后的bin目录下,执行ls会看到两个文件node,npm. 然后执行
./node –v1
2如果显示出版本号说明我们下载的程序包是没有问题的。
- 配置环境变量,
sudo vi /etc/profile1
export PATH的上一行添加如下内容
PATH=$PATH:/usr/local/nodejs/node-v5.9.0-linux-x64/bin1
编辑完成后按Esc键 然后输入 :wq 按回车保存,退出vi ,执行
source /etc/profile1
可以使变量立即生效,然后执行
echo $PATH1
看输出内容是否包含自己添加的内容,然后到任意目录下去执行一次执行
node -v1
2```
npm -v
ok 搞定了,需要注意的是,通过 source /etc/profile
,只是让变量临时生效了,如果此时重新开一个终端运行node会提示找不到命令,这个问题重启或者注销之后可以解决,如果不想重启的话,再次执行 source /etc/profile
即可。
newman 安装
- 官网在这里newman;
- 执行
1
npm install -g newman@2
即可,安装成功后执行1
newman –h
可以显示帮助信息。
mail 安装
- 使用
1
yum search mail
发现有 mailx.x86_64 : Enhanced implementation of the mailx command
说明可以安装,执行1
yum install mailx -y
搞定,执行如下命令即可发送邮件1
echo "this is send content" | mail -s "send from linux" test@test.com
- 默认情况下发送的邮件会被放到垃圾邮件里面,可以执行
1
sudo vi /etc/mail.rc
在其中添加如下配置1
2
3
4
5set from=test@163.com
set smtp=smtp.163.com
set smtp-auth-user=test
set smtp-auth-password=123456
set smtp-auth=login
这样发送的邮件就不会被放到垃圾邮件里面,也可以从文件中获取发送内容,如下1
mail -s "mail title" 123456@163.com < outfile-1458185763.txt
参考:LINUX下通过外部SMTP发邮件 (直接抛弃sendmail和postfix)
插件推荐 - 王进
插件 | 简介 |
---|---|
ParcelableGenerator | Android中的序列化有两种方式, 分别是实现Serializable接口和Parcelable接口, 但在Android中是推荐使用Parcelable, 只不过我们这种方式要比Serializable方式要繁琐,那么有了这个插件一切就ok了 |
GsonFormat | 现在大多数服务端api都以json数据格式返回, 而客户端需要根据api接口生成相应的实体类, 这个插件把这个过程自动化了, 赶紧使用起来吧 |
ADB WIFI | 每天只需用USB线连接一次,就可以将USB连接切换成WIFI连接,去掉讨厌的数据线连接 |