Record 202311¶
优化¶
- 重构算法的异常传递机制;
- 排除不支持的数据类型:
-
kotlin.jvm.function.Function1
-
- 打更详细的日志;
- 通过 process 的输出判断测试用例是否执行成功;
- 获取测试用例执行结果
- 将执行结果存入
TestCase中 - 添加
Config用于选择是否输出执行失败的测试用例
- 为什么会卡住在 Generating population coverage info...?
- 重构 Command 部分:
CoverageGenerator,ExecResolver,Decompiler - 支持
Object的测试- 检测
Object类 - 创建关于
Object类的Action - 生成相关 Jimple 语句
- 支持
whenObject语句
- 检测
- 写一个 bytecode 转 jimple 工具
- 支持
whenStatic语句
问题¶
- 部分行为没有 mock 导致测试用例执行失败
原因:待测函数调用了不属于待测类的函数。
记录¶
Code: MyApplication: com.example.myapplication.jmockk.JMockKTest:test1()
public void test1() {
Example tempExample = new Example();
Example example = JMockK.spyk(tempExample);
when(example, Visibility.PUBLIC, "bar").thenReturn(2);
Assert.assertEquals(3, example.foo());
}
public void test1()
{
java.lang.Object[] $r3;
io.github.maples.jmockk.stubbing.OngoingStubbing $r5;
com.example.myapplication.jmockk.Example $r0, r2;
io.github.maples.jmockk.Visibility $r4;
long $l1;
java.lang.Integer $r6;
com.example.myapplication.jmockk.JMockKTest r7;
int $i0;
java.lang.Object $r1;
r7 := @this: com.example.myapplication.jmockk.JMockKTest;
$r0 = new com.example.myapplication.jmockk.Example;
specialinvoke $r0.<com.example.myapplication.jmockk.Example: void <init>()>();
$r1 = staticinvoke <io.github.maples.jmockk.JMockK: java.lang.Object spyk(java.lang.Object)>($r0);
r2 = (com.example.myapplication.jmockk.Example) $r1;
$r4 = <io.github.maples.jmockk.Visibility: io.github.maples.jmockk.Visibility PUBLIC>;
$r3 = newarray (java.lang.Object)[0];
$r5 = staticinvoke <io.github.maples.jmockk.JMockK: io.github.maples.jmockk.stubbing.OngoingStubbing when(java.lang.Object,io.github.maples.jmockk.Visibility,java.lang.String,java.lang.Object[])>(r2, $r4, "bar", $r3);
$r6 = staticinvoke <java.lang.Integer: java.lang.Integer valueOf(int)>(2);
virtualinvoke $r5.<io.github.maples.jmockk.stubbing.OngoingStubbing: void thenReturn(java.lang.Object)>($r6);
$i0 = virtualinvoke r2.<com.example.myapplication.jmockk.Example: int foo()>();
$l1 = (long) $i0;
staticinvoke <org.junit.Assert: void assertEquals(long,long)>(3L, $l1);
return;
}
错误信息:
22:43:28.573 [ERROR] org.kotsuite.ga.commands.Commands - [main] WARN io.mockk.proxy.jvm.transformation.InliningClassTransformer - Failed to transform class java/lang/Object
22:43:28.573 [ERROR] org.kotsuite.ga.commands.Commands - java.lang.IllegalArgumentException: Java 21 (65) is not supported by the current version of Byte Buddy which officially supports Java 20 (64) - update Byte Buddy or set net.bytebuddy.experimental as a VM property
进展¶
11.2¶
- 完成了 Mock Jimple 的生成;
- 使用
MyApplication对 Mock Jimple 进行测试。
11.6¶
- 使用其它项目进行测试
- Simple-Calendar
- Simple-Calculator
- photoprism-android-client
11.8¶
- 【普通 Kotlin 类】对 Simple-Calendar 中
EventsHelper类进行了测试生成,能生成测试用例集,但由于 mock 的缺陷,测试用例集无法执行成功(缺少when) - 【Object 类】对 Simple-Calendar 项目中
Formatter类进行了测试生成,能正常生成测试用例集
11.14¶
- Bug:ClassPath 太长导致无法创建 Java 进程
- Feat:下一次执行的输出不覆盖上一次的输出
11.16¶
问题:
- 「Core」为什么会没有生成 .class 文件:添加了 try catch
- 「Core」为什么生成 Jimple 的时候会出现未捕获的异常:添加了异常的日志
- 「Plugin」为什么没有识别到模块的 class 路径:没有 Build 成功
- 「Plugin」为什么识别错了 include rules:添加了 selected path 的日志
问题一:静态方法的测试生成「已修复」
报错信息:
21:05:18.577 [ERROR] org.kotsuite.client.MainKt - Algorithm Crash
21:05:18.578 [ERROR] org.kotsuite.client.MainKt - Uncaught exception occurred: java.lang.RuntimeException: wrong static-ness
11.17¶
工作记录¶
- 搭建
SystemUi项目的测试环境; - 对多个类进行测试,完善代码,收集数据。
测试日志¶
SystemUi > oplus_charge > com.oplus.charge.BatteryLevelToDecimalHelper
测试结果:无法测试 原因:该类为手写的单例模式,无法创建测试类的对象
SystemUi > oplus_charge > com.oplus.charge.util.ChargeLogUtil
测试结果:无法测试
原因:
- 当类里面需要有执行顺序时,无法生成正确的测试用例。例如:需要首先执行
init方法初始化类。 - 当类中需要调用具体的
Context方法时,无法正确地 mock,例如:context.getApplicationContext
SystemUi > oplus_charge > com.oplus.charge
测试结果:待分析
SystemUi > monet > com.android.systemui.monet
测试结果:待分析
SystemUi > oplus_common > com.oplusos.systemui.common
测试结果:待分析
SystemUi > seedling > com.oplus.systemui.plugins.seedling
测试结果:waiting
11.20¶
任务¶
- 继续测试其他模块
- 改进覆盖率
- 搜集测试数据
- 完成初版结项 PPT
问题¶
-
Enum类无法获取覆盖率:本身就应该是不用生成测试用例的类 - 数据收集有问题:由于存在执行失败的测试用例,导致部分类的覆盖率存在问题 -> 筛掉崩溃的测试用例
- 通过方法名过滤生命周期函数:
onCreate等 - 统计适用于 AndroidTest 的待测函数,做进一步统计
11.21¶
任务:
- 完成初版 PPT(obsidian, ppt, pdf (QECon), word, excalidraw)
- 继续测试项目,收集测试数据(
SystemUi > oplus_common)
问题:
- 同名类的加载顺序导致测试用例执行失败:取决于 classpath 的顺序
11.22¶
- 任务:搜集每个项目中的数据,有多少类,有多少方法,有多少类能生成,有多少方法能生成,然后以一个 module 做示例
11.23¶
- 绘制项目概览饼图
- 收集
OppoLauncher和OppoGallery3D上其中一个模块的测试执行结果 - 修改 PPT
- 完成简历
- 要专利图片
- 完成附录中的算法实例(以一个类为例)
测试项目¶
- Simple-Gallery
- Simple-Calendar
- Simple-Calculator
- Simple-Commons
- photoprism-android-client
Simple-Calendar¶
测试结果¶
Simple-Calendar: EventsHelper¶
Simple-Calendar: Formatter¶
下一步:
- 继续测试 Simple-Calendar 的其他类
- 重构异常处理机制
- 获取测试用例的执行结果,并据此对最终的测试用例输出做过滤
- 重构 Command 部分
2023.11.09 阶段性提交¶
测试数据:
- 测试项目:Simple-Calendar https://github.com/SimpleMobileTools/Simple-Calendar
- 所有类(去除了匿名类):204
- 可以进行测试生成的类:44
- 可以进行测试生成的方法:227
待测类的特点:过滤条件为 匿名类、非公共类、抽象类、接口类、数据类、包含至少一个待测方法的类,根据这些条件过滤后的类为待测类。
待测方法的特点:过滤条件为 构造函数、匿名函数、抽象函数、Get/Set函数、componentN函数、Android类的重载函数、函数参数包含不支持的数据类型(lambda表达式),根据这些条件过滤后的方法为待测方法。
目前不支持的函数参数的数据类型:lambda表达式类型
2023.11.10 会议记录¶
「技术验收」和「结项验收」一起完成
- 技术验收:
- 技术指标问题:主要是覆盖率指标
- 技术上的优劣势比较:EvoSuite, Diffblue, AIGC
- 结项验收:
- 专利
To Do
- 在更多项目上进行测试,找到最擅长的待测函数类型
- 使用更多的策略提高覆盖率
- 输出覆盖报告(共有多少类、每个类有哪些方法、需要测试的方法有哪些、能测试的方法有哪些、每个方法的覆盖率是多少、能执行成功的测试用例有多少、共有多少个测试用例)
- 输出的测试用例的选择策略(选择不重复的覆盖率最高的,JaCoCo 能否支持?)
- 找 default 出现的原因:函数参数默认值的工厂方法
- 找到**常见**问题的启发式策略:EventsDB, DataTime
待测类和待测方法的分类¶
待测方法:
- 不需要测试:
- 需要测试但无法生成测试用例:
- 能生成测试用例但无法执行成功:
- 能生成正确的测试用例:
待测类:
- 不需要测试:均为 1
- 需要测试
- 需要测试但无法生成测试用例:均为 1 和 2,且至少有一个 2
- 能生成测试用例但无法执行成功:1,2,3
- 能被测:1,2,3,4
Report
Statistic
Reading¶
Knowledge¶
Kotlin 函数参数默认值的底层实现
通过 xxx$Default() 方法实现了函数参数默认值,可以理解为是一个工厂方法。
结项报告¶
项目研究成果 - 工具介绍¶
画图
- Android Studio KotSuite 插件
- KotSuite Core 包:可以在命令行中使用
- JMockK:适配层
项目研究成果 - 用例生成情况介绍¶
能生成 Java 测试用例,HTML 覆盖报告和测试生成报告。
项目研究成果 - 概要设计(零层设计,结构设计)¶
架构的整体设计,分为什么模块。
零层:输入 -> 输出
一层:有什么模块,模块间的依赖关系(Plugin,core,MockK,JMockK)
二层:core 中各个模块的调用关系(client, analysis, ga, reuse, common)
项目研究成果 - 算法介绍¶
遗传算法,用例重用,mock 算法,断言生成算法的介绍。
项目研究成果 - 开源项目介绍¶
JMockK?
项目研究成果 - 实际项目执行情况介绍¶
SystemUi 上的测试结果
各项目上的信息收集结果:
--------------------
项目: SystemUi/
所有类的数量: 1623
不需要测试的类的数量: 1190
匿名类的数量: 1002
非公共类的数量: 3
抽象类的数量: 132
接口类的数量: 0
数据类的数量: 12
包级别类的数量: 41
需要但是无法测试的类的数量: 3
可以测试的类的数量: 430
所有方法的数量: 10961
「不需要测试的类」中方法的数量: 5277
「需要但是无法测试的类」中方法的数量: 46
不需要测试的方法的数量: 3150
非公共方法的数量: 0
构造函数方法的数量: 437
匿名方法的数量: 412
抽象方法的数量: 0
get/set 方法的数量: 619
componentN 方法的数量: 0
生命周期方法的数量: 125
需要但是无法测试的方法的数量: 35
可以测试的方法的数量: 2453
--------------------
项目: OppoGallery3D/
所有类的数量: 5029
不需要测试的类的数量: 4360
匿名类的数量: 3657
非公共类的数量: 476
抽象类的数量: 166
接口类的数量: 0
数据类的数量: 32
包级别类的数量: 29
需要但是无法测试的类的数量: 11
可以测试的类的数量: 658
所有方法的数量: 21975
「不需要测试的类」中方法的数量: 11242
「需要但是无法测试的类」中方法的数量: 258
不需要测试的方法的数量: 6019
非公共方法的数量: 0
构造函数方法的数量: 674
匿名方法的数量: 804
抽象方法的数量: 0
get/set 方法的数量: 578
componentN 方法的数量: 0
生命周期方法的数量: 296
需要但是无法测试的方法的数量: 47
可以测试的方法的数量: 4409
--------------------
项目: OppoLauncher/
所有类的数量: 7822
不需要测试的类的数量: 4714
匿名类的数量: 4199
非公共类的数量: 44
抽象类的数量: 439
接口类的数量: 0
数据类的数量: 28
包级别类的数量: 4
需要但是无法测试的类的数量: 0
可以测试的类的数量: 3108
所有方法的数量: 68518
「不需要测试的类」中方法的数量: 24715
「需要但是无法测试的类」中方法的数量: 0
不需要测试的方法的数量: 23591
非公共方法的数量: 0
构造函数方法的数量: 2911
匿名方法的数量: 817
抽象方法的数量: 0
get/set 方法的数量: 1478
componentN 方法的数量: 0
生命周期方法的数量: 3220
需要但是无法测试的方法的数量: 26
可以测试的方法的数量: 20186
项目研究成果 - 实际项目生成用例特征介绍¶
能生成什么,不能生成什么,为什么
项目研究成果 - 同类工具对比¶
EvoSuite,randoop 优势:能支持 Kotlin,能支持 Android 项目
项目研究成果 - AI 相关对比¶
现有 AI 相关的测试用例生成工具:
| 工具 | 公司 |
|---|---|
| 基于AIGC的蚂蚁新一代测试用例自动生成技术 | 蚂蚁集团 |
| 百度单元测试智能生成实践 | 百度 |
| 基于代码地图的组件测试用例自动生成实践 | 华为 |
| 类chatGPT大语言模型在自动化测试的前沿应用与案例分享 | 腾讯 |
| 大模型助力智能单测生成 | 字节跳动 |
| 华为云基于失败率预测及优化算法的回归用例优选一精准测试实践 | 华为云 |
- 基于 AIGC 的蚂蚁新一代测试用例自动生成技术
- 百度单元测试智能生成实践
- 华为基于现有开源大模型分析需求生成自动化用例探索
项目研究成果 - 验收指标达成情况¶
列出指标和测试用例(待测项目),说明达成情况和未达成的原因。
对于 Android Test,要说明技术难点和未达成的原因。
项目研究成果 - 其它技术指标¶
指标测试情况¶
论文与知识产权¶
PPT 修改¶
Version 1.0 -- Meng
- 复杂环境依赖不算难点?
- 复杂的工具链是难点
- 体现更多和 Android 相关的难点
- 优势:支持 Android 项目的特性描述得更加清楚
- 算法不用讲得太细
- 可以介绍一下工具链
Version 1.1 -- Meng
- P8:替换例子,使用有断言的例子
- P17:搜集三个项目上的数据
- P18:搜集测试生成的数据
- P31:更新数据
- P33:更新专利图片 -- 找玄老师要
- P34, P35:更新项目管理信息 -- 跟玄老师沟通
- P36:更新学生简历
- 添加未来展望
相关项目¶
kotsuite-project/matplotlib_images: 绘图kotsuite-project/overall_statistic: 搜集项目总体信息kotsuite-project/running-data: 搜集项目运行数据
TODO:
- 获取 OppoLauncher 上的执行结果
- 更新简历







.png)


