目标 :1.自动生成单元测试用例并测试边界值,以排查边界异常情况。
2.通过生成网络请求单元测试,以测试接口可用性,多线程网络请求等。
实现思路:扫描所有文件,生成对应单元测试类(在apk 编译前期 aidl 生成java)
1.检索所有java文件 方法 属性(APT annotationProcessor(Android Gradle 插件 2.2 以后))ButterKnife
通过继承AbstractProcessor 可以拿到所有文件根据asType获取到class文件,通过processor可以拿到文件里面的所有方法和属性方法类型参数返回值类型等.
属性类型值
然后通过javapoet生成对应单元测试文件
本质上是将外界传进来的属性值按照Java类格式规范依次转换成String,并将String写进类文件。
单元测试框架
mockito 模拟数据 测试边界值
1)Mockito:简单轻量级的做mocking测试的框架;
2)mock对象:在调试期间用来作为真实对象的替代品;
3)mock测试:在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试;
4)stub:打桩,就是为mock对象的方法指定返回值(可抛出异常);
5)verify:行为验证,验证指定方法调用情况(是否被调用,调用次数, 设置超时时间等);
PowerMockito mock 静态方法
mock静态方法,需要提前打上** @RunWith 和@PrepareForTest注解,@PrepareForTest**这个注解可用于类和方法。
关于** @RunWith 和@PrepareForTest**的使用场景,个人理解就是比较复杂的情形,比如mock私有方法,静态方法,mock在方法内部new的对象,final方法。
Espresso ui自动化测试
ViewMatchers 在当前View层级去匹配指定的View
ViewActions 执行Views的某些行为
ViewAssertions 检查Views的某些状态
Robolectric ui测试
通过实现一套JVM能够运行的Android代码,从而实现突破Android环境进行测试。
1.测试四大组件 (生命周期流程测试 配置可测试页面显示)
2.多线程测试
打印主线程所有方法执行时间
利用Handler.java的sendMessage()、dispatchMessage()方法,找出耗时函数并打印耗时时间
主线程中发送消息,最终会调用sendMessageAtTime方法入消息队列,然后通过dispatchMessage进行消息分发执行。那么我们分别利用这两个方法就可以监控到消息是谁发的,以及这个消息的执行时间。为了能够做到这些,我们利用epic框架对这两个函数进行hook。
执行方法后,可以清楚看到程序中具体是哪里执行了耗时操作:
源码
单元测试配置
app gradle 加 apply from: /m_adr_tools/apt-compiler/config.gradle'
library dependencies 加 annotationProcessor project(':apt-compiler')
apt-compiler/etc/TestData.txt 文件
1.参数 基本数据类型
DateTimeUtils.getCalendar(String.class)#String;
类名.方法名称(参数)#返回值
2.参数为 自定义bean
Param.Bean#json
DateTimeUtils.getCalendar(Bean)#Bean2;
NoTest.txt 不用测试的类
Tclass 泛型对应的类或者接口
结果:
1.在java/test 或者 java/androidtest 里面生成对应测试类
普通类 方法测试
1. 有数值调用 (mock 对象 基本数据类型随机)
2. 空数值调用
3.时间统计
4.可设执行次数
网络测试:
1.多线程 同时抓取log 并请求(测试网络组件 需要打开主app 点击调用要测试的接口位置)(cpu 内存)
2.多线程 读取log文件 并请求log文件里面配置的网络接口请求(可以直接拿 logcat里面的数据 也可以拼接)
3.模拟okhttp请求未配置(加密方式等)
四大组件(检测内存变化 启动时间)
1.activity类 生命周期执行 获取所有子view执行相应操作
2.Service类生命周期流程测试
4.BroadcastReceiver 和 content provider需要自己配置参数(action,查询语句) 会模拟发送广播 和查询数据
编译结果异常展示: 515条 test 2个异常
详细log位置
详细log 展示 test 执行时间 方法执行消耗时常 报错
添加方法超时异常 (例如 设置100毫秒)
相关配置在 config.gradle buildConfigField"int","METHOD_TIME_OUT","100"//单位毫