# WallSina **Repository Path**: gitee-xu-chen/wall-sina ## Basic Information - **Project Name**: WallSina - **Description**: 软件测试,Java自动生成测试工具 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-01-02 - **Last Updated**: 2024-10-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Readme ## 小组成员 徐宸、余东桦、朱岭 ## 项目功能 ### 基本功能 - 设计实现随机测试生成算法支持 Java 基本类型、String、数组、枚举类型和类 - 实现基路径计算算法 - 在方法中没有定义局部变量的情况下,设计实现满足语句覆盖、分支覆盖、基路径 覆盖的非随机测试生成算法,支持 Java 基本类型、String、数组、枚举类型和类, 支持选择和循环逻辑结构 ### 增强功能 - 考虑在方法中定义局部变量的情况下,设计实现满足语句覆盖、分支覆盖、基路径 覆盖的非随机测试生成算法,支持 Java 基本类型、String、数组、枚举类型和类 - 基于数据流的测试数据生成(全定义使用路径覆盖) - 跨越方法的测试数据生成 ## 功能设计说明 我们并没有直接使用本来的代码,而是先研读了 Z3 的一些内容,并且根据 Z3 的特性,进行了重构代码,不使用给定的 Z3Solver 类,而是自建了 Z3 parser 这个新类,集成并能够将各种路径中的节点转化为相对应的路径约束,在其中针对不同类型的变量进行分析,并且在后续的生成测试数据内容中进行了应用,并且自定义了局部变量的表示方法,重现并增强了原本代码的功能 大致的设计流程如下: - 自带的代码可以将一个Java的方法经过Soot转化为unitGraph - 通过对图进行遍历和分析,我们能找到满足各种覆盖的路径,限制访问的路径长度和查询访问到的节点类型,我们能够及时终止。 - 对这些访问到的路径通过 Z3Parser 去解析,能够直接得到一个路径约束,再交给 Solver 去解析,最后能够生成测试数据 ### 计算基路径 基路径的算法集成在基路径覆盖过程中,我们通过深搜算出所有节点开始,走到结束、走到已经访问过的节点或者走到自身,并且将这些得到的路径,反向插入字典树中,那么字典树中如果有一个叶子节点,那么就代表有一个基路径,很好地解决了我们寻找基路径过程中筛选路径的过程,直接取最长的不重复的那个路径,满足基路径的定义。 ### 基路径覆盖 对于每个节点都存储一个 pathState,然后进行广度优先搜索,对于搜索到的每一个节点,都存入当前节点到 pathState 的 unitPath 中,然后对于每当我们访问一步,就可以去字典树中 search一下是否在其中并且最后一个节点为叶节点,如果搜索到,那么就是基路径,将该叶节点设为 isVisited,并生成测试用例,然后继续访问。 #### 揭错能力评估 对于基路径的揭错能力评估就是覆盖了的基路径和整体基路径的比值,此处为了展现原本的效果,因此我们没有去做除法,而是分别展现了原本基路径和覆盖的生成路径的数量 ### 语句覆盖 语句覆盖比较简单,就是对每一个节点进行覆盖,我们只需要维护一个 Set,当遇到路径长度超出固定值或者遇到 Return、和直接退出等语句时,判断一下当前路径是否有之前没有覆盖到的节点,如果存在,那么生成测试数据,如果不存在,那么说明这个测试数据产生的效果已经被之前的包含了,因此直接跳过即可 #### 揭错能力评估 对于语句覆盖的揭错能力评估就是覆盖了的节点和总节点数量的比值,此处为了展现原本的效果,因此我们没有去做除法,而是分别展现了原本节点数量和覆盖的节点的数量 ### 分支覆盖 分支覆盖就是要覆盖到每个分支的两个子分支,我们的思路和语句覆盖大致相同,每当遇到路径长度超出固定值或者遇到 Return、和直接退出等语句时,判断一下当前路径是否有之前没有覆盖到的分支节点,如果存在那么生成测试数据,如果不存在,那么说明这个测试数据产生的效果已经被之前的包含了,因此直接跳过即可。 #### 揭错能力评估 对于分支覆盖的揭错能力评估就是覆盖了的分支节点和总分支节点数量的比值,此处为了展现原本的效果,因此我们没有去做除法,而是分别展现了原本分支节点数量和覆盖的分支节点的数量,如果遇到在运行时间内跑不出来的,就认为是不满足分支覆盖 ### 数据流覆盖 此处我们选择了全定义使用覆盖,既保留了Soot.body 自带的 getDefBox和getUseBox,最后是通过手动通过获取 JAssignment 等语句来获取def 并通过剩余路径来判断是否有 use 来得到 du-path 的代码。主要流程和上述差不多,也就是维护一个Map,存储所有的duPath,记录路径的起始节点和终止节点,每当遇到路径长度超出固定值或者遇到 Return、和直接退出等语句时,判断一下当前路径是否有之前没有覆盖到的分支节点,如果有,那么就加入这个Map,没有,那么这个路径就是无效的。 #### **为什么不选择用getUseBox()** 在测试过程中,我们发现getDefBox() 代码段在部分代码上与我们的结果存在出入,原因是当遇到存在方法invoke的时候,getUseBox无法解析到我们需要的参数,因此,数据流图会因为缺少了部分使用节点而导致缺算、漏算的情况,因此此时需要去手动判断。 #### 揭错能力评估 对于数据流覆盖的揭错能力评估就是覆盖了的du-path和总du-path数量的比值,此处为了展现原本的效果,因此我们没有去做除法,而是分别展现了原本du-path数量和覆盖的du-path的数量,如果遇到在运行时间内跑不出来的,就认为是不满足数据流覆盖 ### 跨越方法的测试数据生成 只要继承了Generator类就会能够实现跨方法,已经集成到之前的各种覆盖中了 ## 项目亮点 - 完成三个高级功能:数据流覆盖、存在局部变量和跨越方法的测试数据生成 - 代码重构:并未完全参照原本的代码,而是自建parser,自定义局部变量 - 代码复用:解耦大师上线,Generator父类,子类继承,代码复用,同时Z3 Parser的存在 也能让我们更好地扩展 - 较大的测试集合:在20个不同的代码中进行了运行,覆盖了各种情况,包括异常情况,能够很好地展现我们的功能 ## 项目未来 - MCDC覆盖暂未实现,因为需要考虑到短路运算符的原因,代码变得十分复杂,有待完成