# JTestGenerator **Repository Path**: cqiin2/jtest-generator ## Basic Information - **Project Name**: JTestGenerator - **Description**: 软件测试JTestGenerator项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-10-15 - **Last Updated**: 2024-01-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 小组成员 # 一、项目内容 基于已有的 JTestGenerator 工具 重构or重新开发,设计实现一个针对 **Java 类中方法**的测试数据生成工具、对开发的工具进行测试、并评估该工具生成测试用例的揭错能力(随机 vs 非随机)。 ## 1.1 被测代码设计 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YjZkY2NmOTRmMjdkM2I5MzFjNGYwNGU4ZjJjMjE1NjRfWnVUU3JWY0xBdm9pY2xqQTVDcU92N3NXWVVuSWNUWjhfVG9rZW46SXZOd2JvRmNsb2ZqQnV4MkIzdGNJeDBsbkVjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ### 特点 1. 涵盖了不同的逻辑结构,如顺序、选择、循环等,可以用于测试不同的控制流和数据流的情况。 2. 条件表达式复杂程度不同,可以用于测试不同的布尔逻辑的情况。 3. 调用自身/外部方法,测试不同的方法间的依赖和交互的情况。 4. 输入输出包含多种类型,测试不同的数据类型和格式。 # 二、基本功能 1. 随机数据生成 2. 实现基路径计算算法 3. 在方法中没有定义局部变量的情况下 设计实现**满足语句覆盖、分支覆盖、基路径覆盖**的非随机测试生成算法。 支持 Java 基本类型、String、数组、枚举类型和类, 支持选择和循环逻辑结构 ## 2.1 随机数据生成 新建了`util`工具包,其中定义`RandomDataUtil`类用于支持随机数据生成的小算法。针对基本类型:整型、浮点型、char、boolean;String;数组;Enum枚举类型;类。 同时完善`SimpleGenerator`中的`randomTC`方法,通过soot提供的`Local`本地变量获取参数类型,执行对应的随机数据生成,特殊的引用类型,则是通过反解析出的类名获取类型。 ## 2.2 语句覆盖 **语句覆盖**:在控制流中每条可执行的语句至少被执行一次 1. 使用getAllCompeletePath函数dfs递归调用生成所有路径,用completePaths记录; 2. 遍历completePaths中的每条路径 2.1 使用calPathConstraint函数求出每条路径上的路径约束 2.2 如果没有路径约束 2.2.1 随机生成测试数据(字符串),加入到testSet测试集合中 2.2.2 通过coverNode函数计算当前已覆盖到的节点集合size,具体实现为:若路径的单元之前没被覆盖到,加入已覆盖的节点集合,并返回当前节点集合的size 2.2.3 判断如果已覆盖到的节点总数等于总节点数,则跳出循环 2.3 如果计算出路径约束 2.3.1 通过z3处理器求解,Z3Solver.*solve*(pathConstraint) 2.3.2 通过coverNode函数计算当前已覆盖到的节点集合size,并于当前覆盖节点数coverNodeCnt对比,若此路径没有覆盖到新的节点,直接进入下一条路径,反之,更新已覆盖节点数,并把z3处理得到的字符串解,转化为所需要的测试输入参数(对象),再把对象转换成字符串,存入测试集中,并计算出预期结果加入预期结果集。 2.3.3 判断如果已覆盖到的节点总数等于总节点数,则跳出循环 1. 根据覆盖的节点数/总结点数,计算出语句覆盖率。 ## 2.3 分支覆盖 **分支覆盖:**在控制流图内的每一条边都至少被执行一次 1. 初始化时计算出函数的节点数,用二维数组存储CFG中的边 2. 使用getAllCompeletePath函数dfs递归调用生成所有路径,用completePaths记录; 3. 遍历completePaths中的每条路径 3.1 使用calPathConstraint函数求出每条路径上的路径约束 3.2 如果没有路径约束 3.2.1 随机生成测试数据(字符串),加入到testSet测试集合中 3.2.2 通过coverEdge函数计算当前已覆盖到的边集合size,具体实现为:若路径中的边之前没被覆盖到,加入已覆盖的边集合,并返回当前已覆盖边集合的size 3.2.3 判断如果已覆盖到的边总数等于总边数,则跳出循环 3.3 如果计算出路径约束 3.3.1 通过z3处理器求解,Z3Solver.*solve*(pathConstraint) 3.3.2 通过coverEdge函数计算当前已覆盖到的边集合size,并于当前覆盖边数coverEdge对比,若此路径没有覆盖到新的边,直接进入下一条路径,反之,更新已覆盖边数,并把z3处理得到的字符串解,转化为所需要的测试输入参数(对象),再把对象转换成字符串,存入测试集中,并计算出预期结果加入预期结果集。 3.3.3 判断如果已覆盖到的边总数等于总边数,则跳出循环 1. 根据覆盖的边数/总边数,计算出分支覆盖率。 ## 2.4 **基路径覆盖** ### 2.4.1 基本思路 1. 首先通过generatePPCCompletePaths函数计算基路径和完整路径集合 1.1 通过dfsSimplePaths函数,以每个节点为初始节点,根据每个初始节点计算简单路径,并存储simplePaths 1.2 对处理出来的简单路径集合进行筛选,删除掉所有作为其他简单路径子路径的路径,并按照路径长度反序排序,将筛选后的路径集合记为基路径集合primePaths 1.3 将基路径延伸到完整路径:对每条基路径进行延展处理,并找到头尾节点,生成新路径,同时删除基路径集合中作为新路径子集的基路径,最终得到完整路径集合completePaths 1. 遍历completePaths中的每条路径 2.1 使用calPathConstraint函数求出每条路径上的路径约束 2.2 如果没有路径约束:随机生成测试数据(字符串),加入到testSet测试集合中 2.3 如果计算出路径约束 2.3.1 通过z3处理器求解,Z3Solver.*solve*(pathConstraint) 2.3.2 若z3处理器无解,则在完整路径集合中移除此条路径 2.3.3 若处理器有解,把z3处理得到的字符串解,转化为所需要的测试输入参数(对象),再把对象转换成字符串,存入测试集中,并计算出预期结果加入预期结果集。 1. 对基路径集合primePaths中每条路径进行判断,若是任意一条有解的完整路径的子集, ​ 则记为此基路径被覆盖,统计被覆盖的基路径条数。 1. 根据覆盖的基路径数/总基路径数,计算出基路径覆盖率。 ### 2.4.2 测试用例分析与评估 可以看到在以下测试用例中,基路径覆盖率除了2和4都为1,生成测试用例的效果较好。 1. forIfOfArr ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MjY3YjEyYjU0OGJjY2VlMTQ2NjliNDA1ZTM5NWZiNWZfMmlLMHNnM1R2MldjZkx5bmNzTlNIMzZubVFoeVNRbDNfVG9rZW46RVFNQmJWM2ZUbzlRU1B4dndYNWNCeEdqblRnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. testSoloWhile ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ODgyNGViMTM2MzZjNTI1MTM4NmYzYjJhOTJhMDE0NDVfZDZ4VlZCdU1qTGl1Zlh6VGhVckpuZXBTam5uSHVMdVJfVG9rZW46UzlrYWJGSldWb21xUEZ4eTRFSGMxV1V4blpnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. forOfDouble ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YjFiMmQzNjYzMWZlMzcwZjcyNDc3ZjM3NTUxMzgxN2VfdEw1bkNsQXMxMHB6ZndBVVNiZDJYdU84TmdhbThCa1lfVG9rZW46VE5oQmIwUkxrbzNoVHV4Tkp5SmNSSXRibjlnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. ifOfBoolean ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MmRhMDQxYjNhZmU2YzkwZWFhZTg2Njc4ZDI3MTRhYTZfb3RPVzFrQzNpV2R5VmhqRmFZOG1vNmVQVmx6QWw4bW5fVG9rZW46T25ta2JlOUxmbzFjZzV4VnlBbmNqeG10bnhjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. finalTest ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NWJiZjRlYmQ2NDE0MmZiNWExMzllNGE5NjgyN2QzMjdfaXZveXJKSHhZOFN2UlhvZ0xSZUo1YUQ4MGZUaXhBNG1fVG9rZW46RFNMOGJhNWFZb0dyVDN4RTdYYmNFVFV3bkhlXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. ifOfChar ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YWYwMWVhYTIxNGUyOWU4NTg5N2MyNWUzZTY5NzFiMTNfcXViMVpLRU5YWkpiaG8zVXhvSjE3bGxTbzNiZnkyUGFfVG9rZW46SjB1Q2JkZVZlb2tINVF4dFNlb2NKa05NbjlqXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. multiple_if_correct ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YzZkMTU4OWQxOGYyM2M2ZjI1YmQwMTZlMDE4ZWQ0MzBfVVVjZ0RNZGhyWXBuTktyeXR4aFFKRmpkaEJmNGtvUWJfVG9rZW46V1hCMWJvSFRab1Z5emR4WGY4ZGNpbktFbjBaXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. ifForEnum ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZWNlOTI3NzgyMzU4MDU1ZTlmZTIxNjRlZTM2MTdjNGNfWk9FSGpXTHVNRHM1NFprU3FwbDhqUTJxTU0xbGpWTG1fVG9rZW46Q3hTSGJjeElBb1lrVzR4RXBYcmMxR0xGbm9jXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. invokeTest ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NGQ4NGIzNmMxYTNkN2MyMWVhZDQ5ODdiMWY5OTJiZjZfYkJCWWVmSk05SFdxYXFWUmJNbkl0MjRBRVpLUVVUczdfVG9rZW46SEwxcWJFa3Rxb0ZCYlB4dUpvdGN0cEhXbmRnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. loop_for_person_correct ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NDY4ZTlmYjk0OGU5MjM2MmQwMjk4N2ZiMjdjZDBhNjlfU1VWRkFpVE5NZ2FjZnFhMWpoTXZibDRBUUFOd1NHQjNfVG9rZW46VHMzTWJHeE5rb3JhdGt4U2t2VmM2THVJbjhkXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ### 2.4.3 尝试 使用DDL方法计算基路径,将每个节点展开图视作一颗多叉树,判断多叉树是否互为子树。 1. 将block转化为多叉树 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YmMzYjg3MTZhMzQwZjAyZTQ2YzI3NDM0NTNmNmZjN2FfTTBpM2V6TzRQY0JuM0JsWUJ5V0tkeURoSlluVmw3YnNfVG9rZW46VEhwdWJORExTbzJqc3Z4dmV2ZWN3YngzblRkXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 计算基路径 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MmQ5NzQzZDlmMTkxZGE5N2ZkNjViMDVkYzJkN2Y5N2RfaVpwazRVVnJUeFFqc3hZRThvQnNCNmdpY0RUMVA0NkRfVG9rZW46RGIwTWJPSkZkb3dETWJ4Q1owZ2NBTWlTbjV6XzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 判断是否互为子树 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=Yjg0MWE4NjVlZTc3NWRjOWIwODkxYzFkYTRmYzMyZjlfVzFMNmprTU4ybGM5a1NOZmpOQUJUWmZWWjIzeGJCMlhfVG9rZW46T2k3MGJyZHZ0b043dEp4dGNqa2NzM1lMbjljXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) # 三、增强功能 ## 3.1 MC/DC测试数据生成 **MC/DC覆盖:**要求实现条件覆盖、判定覆盖,每个条件都要独立影响判定结果。要求: 1)条件C所在判定内的所有条件,除条件C外,其他条件的取值完全相同。 2)条件C的取值相反,判定的计算结果相反。 ### 3.1.1 生成流程 1. 针对指定的类与方法信息,调用iniDecisions()和iniSplitContent(filePath)函数进行初始化。 A. iniDecisions()负责根据soot划分的代码基本块,筛选所有的if语句(JIfStmt),并且调用getJavaSourceStartLineNumber()函数获取行号,如果当前语句没有在decisions(该集合用于存储条件语句以及对应行号),将该条件语句加入decisions。 B. iniSplitContent(filePath)负责根据文件路径读入文件,将每行代码存入splitContent中。 1. 调用generate()函数计算MC/DC数据。生成的测试用例存储于sootTestSet中。 1. 双层循环遍历生成代码中的每一条路径。 2. 遍历每一条路径: 1. 如果是赋值语句,将其改写,存入assignmentList. 2. 如果是条件语句,遍历每个条件,替换条件里的局部变量,并将处理过的条件添加到conditions里,计算每个条件独立影响的情况,移除处理过的行号。对于每个条件生成一个z3表达式利用Z3Solver进行求解,将结果存入sootTestSet中。 1. ​ 根据行号获取逻辑运算表达式,对于if/while获取()内的条件,对于for(;con;)获取con。改写逻辑运算表达式, 3. 对于sootTestSet中的每一个测试用例,将其测试数据和结果分别加入testSet和expectedResultSet,返回testSet,并且计算MC/DC覆盖率(coveredCnt/conditionCnt) ### 3.1.2 测试用例分析与评估 对以下代码生成测试用例,可以看到除了3和5的MC/DC覆盖率都为1,生成效果较好。 1. forIfOfArr ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZWEyOTQ4YTMwNzAwMWVmOGVhZDRiMGViNTU4MDQzZWZfWkIwVFZ4RDNPZ2pkSjBBZU5CVEVTOVc5aWtzeTdMRkdfVG9rZW46RWdEWmJ3VzJDbzQ0VDl4dEkwQ2NsMXNqblRnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. forOfDouble ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=OGU5ODY2NmEwNmQ5MDNjMjUyYjM1YzFkM2JhNzk1NDVfSFU3QlBLRTlLTTJ1Q0RKOUNMWXBrZGRFbFFyQTA5NG1fVG9rZW46SldqcmIyd20ybzN5TUF4N0oxOWN4T0RWbmFnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. ifOfBoolean ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YzJiOGU0NzNmNjQwOTdkMGQ3N2ZiNDM4MzkzYjc2ZjNfSlM0aEZON2Z5dlVJZmg3eEM0c2JaUFZTSmRGeWVtZThfVG9rZW46SDRJVGJ6Zmdzb1NEUE14QUUyS2NVdVp5bk5kXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. finalTest ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MGYzZTExMzA0YzMxMGVhZjgzZGU5MDljZTFhMmFmOTRfNjZiS2lNeUJGY1ZnZFpmWXRJTnhMSVZSQWxNem1va1pfVG9rZW46VnV4b2JUSWVSbzBHVDh4NHQ3WmN1VEJjbnRnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. multiple_for_correct ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NzllNWRkYWMwNmEzYWI2N2ZkYjIxOWQ1MDBhNWUyODNfOXRQb0VFbTg2eFRnYTJtNkl6QjMyNnB1YUFhWWNzWExfVG9rZW46SzRESmJRZUI1b2VwR0N4UjB1OWNNZFR5bnpkXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. ifOfChar ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NGU4NmM2YmI5NDdkOWI4ZWJmNGVkNGY2MDFhYTNhZDJfOVlRYll5OUpsNU1aUGlJNFlhQUt5U3lmN3Y4ZERWb0RfVG9rZW46WGJnZ2JiTXJVb0Y5bm14REt0RmNDNHRpbm9nXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. multiple_if_correct ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NDllYmZlOGRmYmFmZDIxYjgyN2FkMWY5ZjliNWYxMTRfckVMMDRqTW1MVXdsallDRWRjTW5aZ2llSHp5OWVzbVdfVG9rZW46RGs0bmJHVXE2b1BJc0Z4YXpPY2NVYkhlbmVlXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. testSoloIf ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZWE2Yzk4Nzc3Yjk5NTNhYmVmYzIxZTk2Njk1MTE0NTNfZjRRRU1LSFU5TnVOYjRpTzNhVkx3cFM5ekVxTjROMHZfVG9rZW46QVBVU2JQajdQbzQ5Nnd4cXVxZmNucTdPbmZjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. invokeTest ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YzJkODE5N2UxODc0NDA5MDA3NTFjNjk3NWJhZWU3YWVfMHdIR01YWndnMU9xMU16WWxicFhmTUszVDI4YVhOSXNfVG9rZW46QTlzTWJudnZTb3I1S3h4d1duR2NGRXZXbnhlXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. loop_for_person_correct ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YjU1ODcyMTJjOTI1NjgxMmExMDc5MDA3ZGMwYjY4OWFfZXNXR0s5bm1OU0lUWFc3dEtsMkVlbm0wd3FrQUN4WmhfVG9rZW46QkZ6YmJEU3JEb1RTQkZ4aGJWNWNSczQ0bkZjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ## 3.2 基于数据流的测试数据生成 ### 3.2.1 生成流程 1. 定义: 1. `DefUseUnit`类,表示定义和使用关系。 2. `DUPath`类,表示定义使用路径。 2. 获取变量的def和use对应的unit: 1. 利用Soot提供的`getDefBoxes()`和`getUseBoxes()`方法,获取变量的def和use结点,分别存储在`defSet`和`useSet`中。 3. 构建def-use路径 duPath,遍历所有变量,然后遍历该变量所有的def/use结点 1. 利用DFS算法实现路径搜索,完善当前变量的duPath合集。 - 具体实现:以一个def为起点,构建到任意use结点的路径集合。 4. 测试用例生成,由三个方法分别生成: 1. 对每个完整路径,利用z3计算路径约束,同时判断是否在duPath集合中,实时更新待覆盖的duPath集合。 对有路径约束的,用`randomTC`方法生成随机数据,构造用例。 如果,利用项目中随机数据生成工具,根据类型随机生成数据。 2. 全定义覆盖 `generateAllDefsCoverage()` 3. 全使用覆盖 `generateAllUseCoverage()` 4. 全定义-使用覆盖 `generateDuPathCoverage()` 5. 覆盖路径计算,判断完整路径集合是否覆盖了特定的duPath,从而计算覆盖率。 1. 对每个变量的duPath,检查当前路径是否完全覆盖即可。 2. 全定义覆盖`coverNodeAllDefsForAPath` 3. 全使用覆盖`coverNodeAllUseForAPath` 4. 全定义-使用覆盖`coverNodeDuPathForAPath` ### 3.2.2 测试用例分析与评估 1. 以LogicStructure的`invoke`方法、loopForPerson为例 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YWRiODY3YTA2MzM5ZDIwZTdiYTg0ZTk3MmY1NTRjMGRfUm5TN0NzTE94VlNYTDd5cEgwaGZIamttbW12bm1hZnRfVG9rZW46RzlhVmJsNG4zb1RqZW14OVh5TWM1OVhIblVjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NjFlMGQzNzViMDNjY2RiMDE2ZWE0MGE3MGY5MzU5OGFfeURRektkSWdzN1NOUjJqUVBVeHZidVRNVW5NMGVwbGxfVG9rZW46U0VnUmJHUEVUb0wzcHh4Y0t6aWNFQ0EybjFmXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 覆盖度达到100% 1. 对forIfOfArr方法 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NDg5OTA4ZjI0Nzc4MjE5NDFhMjUwNzJjYWZmOTM3ZmZfVDFTMGN0c2MwdFJYTlhKN05hNWQ3NTY0NFQ4V1l5M3ZfVG9rZW46QVAyY2Jra0JPbzA4SDh4T2xqbWNyd0hQbjlkXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 对soloIf方法 2. ifElse方法 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZDg1OGM4MmZhZjEwNGY4OGM3YWU5MjgzYmU2MTRlYTlfRXNscGtIYzF1aFVSb3BxYmx3Z0VoSVNnYUN6U21tblJfVG9rZW46TXpnR2JZN1Byb1lacFJ4eWQzeWNvRVZKbkFJXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=M2Y2N2U3OWZjNmUwYzU4NmExMTkwN2JkOGQzYWNiYzFfVjloMHlGR2VCYTBmbUFieHVGWkw5SDVodlBxTVlkZ0JfVG9rZW46RUVPemJ3TlBIbzJKUWJ4VmEzamNNT2g4bmtnXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 对sequence方法 2. multipleIf方法 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=Nzk0ZWYyMzk1OGIzYzkyZmE0ZGQwMTM1ZmViNTJjZWJfbnlvQTRIUFlGM29oQmFJMjJKSFFibk9VRXlSbGtVOWlfVG9rZW46S2FTVGIwYjhsb2dNT2Z4ZFZRMWN6aW1zblJkXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=YTM0MTk4YWI4ZGM0ZmMyMGViMzA2MTYwMWY1ODk5MjlfS1FEck5wNUZjNUlBdm12cE5yUTlZTXdqQ3V6bjg3eXFfVG9rZW46RUpvS2I2RWdmb0d3R0F4TVI3VGNQN0JtblJmXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZDczMDE3NTdiMDBkNjc0NjA2OTI3OGNkZDQ5YTgyZDVfdHhsUHVPVGJMZ2VjUHVjcEJsSTVYNUFXVHI5WVdnZFFfVG9rZW46QmFtTWJhbzdpb2ZTTjN4ZWtwaGMyVHkybklmXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 对finalTest方法 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MTc3NGU3ODljYjRkODAyZjRiOTA5N2RkNDg3NWUxZjZfOVpqa1ByYWlRTENSdU1KRG84eVVaeEZxekhVazlLdUFfVG9rZW46UHdWb2JHc0FEb0ZadE54VzRZVmNMb3Z1blFLXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=OTM0MjRlMGRkOGQ2NjI4NTVjZGY4YzhkMzM1OWY5MzhfbjVSN2ZYeHFCbmxISHJBNHc1QW1WclczSXl0UzQzcGdfVG9rZW46WDNINGJzb0pGb3RIRlp4VmRvc2NUdDVWbjliXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) 1. 对simpleSwitch ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NThkMmVkOWU2ZWU3OTA3Nzg3NjU4ZmU2MGExNTNlNDJfaHJ5blNXeFJ2VkhJZGpsZHBSQWlGU3ZmZWk2WjBEYVhfVG9rZW46Rzg2cWJxSjUxb3ZkcGJ4eTd5YWNvY29hbjBmXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=OWRhMDVkOGYwOTYwZjljMmNmNDJlNTc3YTBkNjg0ZGZfRjg0Y0M4dUVhVmZJbEtJWTVxcExnd3BhTmtkazZDSzhfVG9rZW46TnpMb2JDZVF0b3B4UTF4cmt2dmNDN3NUbjliXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ### 3.2.3 不足 测试过程中发现,对`mutipleFor`的测试用例生成,并不能达到100%的全定义-使用覆盖度,然后分别观察了全定义覆盖和全使用覆盖,观察到不足主要在全使用覆盖上。根据本地测试情况,生成的参数a的范围与res的大小密切相关。这是项目中随机数据生成不足的地方。 同时将变量res的值假如放大到50,覆盖率就会大大减小,因为if中所有结点都执行不到了。 ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=MTg5Yjc3ZTlmYjBjYTljZGZlMzg5Y2ZlOTc0MGZiMWFfNXJlZDB1WFFCd2MzR3pqYWtBcHJkbjJZWGhnS2p0dm5fVG9rZW46SU1Jd2JHUk95b0J5ZzN4Z2phc2NuTFVIbnFmXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=ZGFlMjFmNTRkYzE2M2NmMjQwNjE5ZDU2YTYxYmEzZWZfaU1mSDhudFFNaDZ1SkdHaFdjYWhTRWxKcmVmcDFyZk5fVG9rZW46RzZINGJaUkVub3ZVUWR4S3hsSWNvb0FZblBjXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) ![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=OGRiZjNmZDU0OTliMTJhNWUyZjA2NTYwYjUxNDUyN2RfbHk2bHFFYmZYZGVsajVJRjkybWxVbklreTI1MnpRUjRfVG9rZW46TFRUMGJadmRxb2JxSFR4bzYyMGNkS0lCbm9lXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA)![img](https://r0o7ljwxopa.feishu.cn/space/api/box/stream/download/asynccode/?code=NTY1MDk4NTM0OTg3MWQwMDcxYWVmNTc1YjNjYmU4NDZfQ0pPeUNDbEFzTkFvcnBqdlk2WTR0dUtkcnByVDNBQ1VfVG9rZW46U0JFeWJ6ZkRjb0pQRjV4dzZjM2NtY05CbkJlXzE3MDQzNjE4NzY6MTcwNDM2NTQ3Nl9WNA) # 四、项目亮点 - 架构清晰,工具包放在`Util`工具包中,更有利于简化代码编写流程,更适合小组分工;可拓展性也有提高。 - 代码注释清晰,小组代码编写过程中有添加较多注释,以提高可读性。 - 实现了基于MC/DC和数据流的测试用例生成,且覆盖率结果较好。 - 被测代码覆盖逻辑结构多,且条件表达式复杂程度不同。有些调用自身代码而有些调用外部方法,可以测试不同方法依赖和交互的情况。代码输入输出类型不同,增加了复杂程度。 - 使用z3求解器,可以处理条件分支和循环结构,支持布尔逻辑,提供对Java的接口。 # 五、反思 1. 使用部分覆盖准则生成的测试数据并没有满足覆盖率全为100%,说明测试用例生成代码还有一定改进空间。 2. 在被测代码中,仍有一些复杂的语句并没有被包含,例如do-while。并且对于一些变量类型(如数组和字符串),只测试了对长度函数的调用,并没有测试其他函数。并且对对于部分数据结构(如vector)也待测试。 3. Z3求解器本身缺陷 1. 不能保证找到所有的可行解,只能找到其中一个或者判断不存在可行解. 2. z3求解器可能无法处理一些特殊的逻辑,如非线性算术,量化逻辑,模态逻辑 # 六、源码 1. src/main/java/jtg/generator:测试用例生成器和工具类 2. src/test/java/cut:被测代码 3. src/test/java/jtg:测试运行代码