移动周分享-第48期

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框架
  • Robolectric

    • Android Studio配置

      • build.gradle添加库

        1
        testCompile "org.robolectric:robolectric:3.0"
      • Build Variants设置
        Unit Tests

      • Linux和Mac平台的需要配置下才能运行:在Android Studio中run边上有一个app选择,这里选择”Edit Configurations” 出现编辑界面
        Run/Debug Configurations
        在左边中新建JUnit,Default->JUnit
      • 测试代码
      • 中间出现问题
        • Android SDK目前只支持到22,5.1
  • 单元测试的目标函数主要有三种:

    1. 有明确的返回值,如上图的dosomething(Boolean param),做单元测试时,只需调用这个函数,然后验证函数的返回值是否符合预期结果。
    2. 这个函数只改变其对象内部的一些属性或者状态,函数本身没有返回值,就验证它所改变的属性和状态。
    3. 一些函数没有返回值,也没有直接改变哪个值的状态,这就需要验证其行为,比如点击事件。
    • 既没有返回值,也没有改变状态,又没有触发行为的函数是不可测试的,在项目中不应该存在。当存在同时具备上述多种特性时,本文建议采用多个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.gz

1
解压,进入解压后的bin目录下,执行ls会看到两个文件node,npm. 然后执行

./node –v

1
2
如果显示出版本号说明我们下载的程序包是没有问题的。 
- 配置环境变量,

sudo vi /etc/profile

1
export PATH的上一行添加如下内容

PATH=$PATH:/usr/local/nodejs/node-v5.9.0-linux-x64/bin

1
编辑完成后按Esc键 然后输入 :wq 按回车保存,退出vi ,执行

source /etc/profile

1
可以使变量立即生效,然后执行

echo $PATH

1
看输出内容是否包含自己添加的内容,然后到任意目录下去执行一次执行

node -v

1
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
5
set 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连接,去掉讨厌的数据线连接