Skip to content

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 语句

问题

  1. 部分行为没有 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

工作记录

  1. 搭建 SystemUi 项目的测试环境;
  2. 对多个类进行测试,完善代码,收集数据。

测试日志

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

  • 绘制项目概览饼图
  • 收集 OppoLauncherOppoGallery3D 上其中一个模块的测试执行结果
  • 修改 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 阶段性提交

测试数据:

待测类的特点:过滤条件为 匿名类、非公共类、抽象类、接口类、数据类、包含至少一个待测方法的类,根据这些条件过滤后的类为待测类。

待测方法的特点:过滤条件为 构造函数、匿名函数、抽象函数、Get/Set函数、componentN函数、Android类的重载函数、函数参数包含不支持的数据类型(lambda表达式),根据这些条件过滤后的方法为待测方法。

目前不支持的函数参数的数据类型:lambda表达式类型

2023.11.10 会议记录

「技术验收」和「结项验收」一起完成

  • 技术验收:
    • 技术指标问题:主要是覆盖率指标
    • 技术上的优劣势比较:EvoSuite, Diffblue, AIGC
  • 结项验收:
    • 专利

To Do

  • 在更多项目上进行测试,找到最擅长的待测函数类型
  • 使用更多的策略提高覆盖率
  • 输出覆盖报告(共有多少类、每个类有哪些方法、需要测试的方法有哪些、能测试的方法有哪些、每个方法的覆盖率是多少、能执行成功的测试用例有多少、共有多少个测试用例)
  • 输出的测试用例的选择策略(选择不重复的覆盖率最高的,JaCoCo 能否支持?)
  • 找 default 出现的原因:函数参数默认值的工厂方法
  • 找到**常见**问题的启发式策略:EventsDB, DataTime

待测类和待测方法的分类

待测方法:

  1. 不需要测试:
  2. 需要测试但无法生成测试用例:
  3. 能生成测试用例但无法执行成功:
  4. 能生成正确的测试用例:

待测类:

  • 不需要测试:均为 1
  • 需要测试
    • 需要测试但无法生成测试用例:均为 1 和 2,且至少有一个 2
    • 能生成测试用例但无法执行成功:1,2,3
    • 能被测:1,2,3,4

数据结构图

Report

Statistic

Reading

Knowledge

Kotlin 函数参数默认值的底层实现

通过 xxx$Default() 方法实现了函数参数默认值,可以理解为是一个工厂方法。

代码生成类任务评测集

软件工程中的大模型:confuse-ai

结项报告

项目研究成果 - 工具介绍

画图

  • 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 项目

  • 蚂蚁测试用例智能生成技术架构与实践 SmartUnit
    • 官网
    • 推文
    • 算法:遗传搜索 + 自动断言 + 动态符号执行

项目研究成果 - AI 相关对比

QECon: LLM 助力下的测试能力创新

现有 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 上的执行结果
  • 更新简历