北京网站建设好,360建,app开发公司招聘,湖南湘信建设工程有限公司网站背景介绍
博主目前要做的工作需要将一个java项目的所有RD手写的测试用例和被测方法对应起来#xff0c;最后将得到的结果存入一个json文件。
本教程以项目GitHub - binance/binance-connector-java 为例。
结果展示
最终会得到一个 funcTestMap.json#xff0c;里面存放着…
背景介绍
博主目前要做的工作需要将一个java项目的所有RD手写的测试用例和被测方法对应起来最后将得到的结果存入一个json文件。
本教程以项目GitHub - binance/binance-connector-java 为例。
结果展示
最终会得到一个 funcTestMap.json里面存放着focal func(被测方法)和对应的test case. 实现原理
1. 解析被测项目的src\main目录下的源码将每一个java源文件中的方法声明(MethodDeclaration)存进一个map其中key是方法名value是完整方法题。
2. 解析被测项目的src\test\java\unit目录下的测试文件对于每一个测试文件中的方法声明如果方法名以test开头则认为是测试用例进入下一步。
3. 解析每一个测试用例获取该测试用例的调用的所有方法MethodCallExpr如果该方法存在第一步所得到的map当中则认为该方法是测试用例的被测方法和测试用例一起存入结果json数组中。
局限性
没有考虑到overload的情况。由于是根据方法名称而不是名称参数类型作为方法的标识符。在存入阶段遇到重载的方法后面进的会覆盖掉之前的在召回阶段仅仅使用方法名称来查找方法体有一定的几率找到错误的被测方法。
完整代码
项目结构如下 JsonCreator.java
package org.example;import com.github.javaparser.ast.body.MethodDeclaration;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Map;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;public class JsonCreator {public static void createAndSaveJson1(MapString, MethodDeclaration map, String saveJsonPath) {JsonArray jsonArray new JsonArray();for (Map.EntryString, MethodDeclaration entry : map.entrySet()) {JsonObject keyValue new JsonObject();keyValue.addProperty(key, entry.getKey());keyValue.addProperty(value, String.valueOf(entry.getValue()));jsonArray.add(keyValue);}Gson gson new GsonBuilder().setPrettyPrinting().create();String jsonOutput gson.toJson(jsonArray);try {Files.write(Paths.get(saveJsonPath), jsonOutput.getBytes(StandardCharsets.UTF_8));System.out.println(JSON file saved successfully to saveJsonPath);} catch (Exception e) {System.err.println(Error writing JSON to file: e.getMessage());}}public static void createAndSaveJson2(MapMethodDeclaration, MethodDeclaration map, String saveJsonPath) {JsonArray jsonArray new JsonArray();for (Map.EntryMethodDeclaration, MethodDeclaration entry : map.entrySet()) {JsonObject keyValue new JsonObject();keyValue.addProperty(focal func, String.valueOf(entry.getKey()));keyValue.addProperty(test case, String.valueOf(entry.getValue()));jsonArray.add(keyValue);}Gson gson new GsonBuilder().setPrettyPrinting().create();String jsonOutput gson.toJson(jsonArray);try {Files.write(Paths.get(saveJsonPath), jsonOutput.getBytes(StandardCharsets.UTF_8));System.out.println(JSON file saved successfully to saveJsonPath);} catch (Exception e) {System.err.println(Error writing JSON to file: e.getMessage());}}}
TestMethodAnalyzer.java
package org.example;import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.github.javaparser.utils.SourceRoot;import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class TestMethodAnalyzer {private static final MapString, MethodDeclaration methodMap new HashMap();private static final MapMethodDeclaration, MethodDeclaration funcTestMap new HashMap();public static void main(String[] args) throws IOException {// Load and index all Java files from the main source directorySourceRoot mainSourceRoot new SourceRoot(Paths.get(C:\\dataset\\binance-connector-java\\src\\main));mainSourceRoot.tryToParseParallelized().forEach(TestMethodAnalyzer::indexMethodDeclarations);System.out.println(The size of the map is: methodMap.size());String saveJsonPath1 C:\\codes\\Java\\extract_func_test_pair\\src\\main\\java\\org\\methodMap.json;JsonCreator.createAndSaveJson1(methodMap,saveJsonPath1);// Now parse the test filesSourceRoot testSourceRoot new SourceRoot(Paths.get(C:\\dataset\\binance-connector-java\\src\\test\\java\\unit));testSourceRoot.tryToParseParallelized().forEach(TestMethodAnalyzer::analyzeTestClass);System.out.println(The size of the map is: funcTestMap.size());String saveJsonPath2 C:\\codes\\Java\\extract_func_test_pair\\src\\main\\java\\org\\funcTestMap.json;JsonCreator.createAndSaveJson2(funcTestMap,saveJsonPath2);}private static void indexMethodDeclarations(ParseResultCompilationUnit result) {result.ifSuccessful(cu - cu.findAll(MethodDeclaration.class).forEach(md - {md.setJavadocComment((JavadocComment) null);methodMap.put(md.getNameAsString(), md);}));}public static void analyzeTestClass(ParseResultCompilationUnit result) {result.ifSuccessful(cu - {cu.accept(new VoidVisitorAdapterVoid() {Overridepublic void visit(MethodDeclaration md, Void arg) {super.visit(md, arg);if (md.getNameAsString().startsWith(test)) {analyzeTestMethods(md);}}}, null);});}private static void analyzeTestMethods(MethodDeclaration md) {ListMethodCallExpr methodCalls md.findAll(MethodCallExpr.class);for (MethodCallExpr call : methodCalls) {MethodDeclaration method methodMap.get(call.getNameAsString());if (method ! null) {System.out.println(Test Method: );System.out.println(md);System.out.println(Calls Method body:);method.setJavadocComment((JavadocComment)null);System.out.println(method);System.out.println(---------------------------------------);funcTestMap.put(method,md);}}}}
maven依赖
只有两个(位于pom.xml)
dependenciesdependencygroupIdcom.google.code.gson/groupIdartifactIdgson/artifactIdversion2.10.1/version/dependencydependencygroupIdcom.github.javaparser/groupIdartifactIdjavaparser-symbol-solver-core/artifactIdversion3.26.0/version/dependency
/dependencies