Junit4遇上chatGPT

news/2025/3/15 4:02:02/文章来源:https://www.cnblogs.com/Jcloud/p/18235112

这是一篇适合Java工程师体质的AI开发教程。

本教程会教你写一个简单的junit4的Rule,该Rule在基于junit4的测试方法失败后,自动向GPT发送错误信息并通过GPT分析得出代码修改建议。

首先向AI问好

简单的通过AI,让它基于json格式生成相应的类文件,这样方便我们在代码中使用,而不用显示写json字符串。

package com.jd.jr.parrot.llm;import lombok.Data;/*** created on 2023/7/25 20:07** @author Dragonchu*/
@Data
public class Choice {private String finish_reason;private int index;private Message message;
}
package com.jd.jr.parrot.llm;import lombok.Data;/*** created on 2023/7/25 20:07** @author Dragonchu*/
@Data
public class Message {private String role;private String content;
}
package com.jd.jr.parrot.llm;import lombok.Data;/*** created on 2023/7/25 20:06** @author Dragonchu*/
@Data
public class Usage {private int completion_tokens;private int prompt_tokens;private int total_tokens;
}
package com.jd.jr.parrot.llm;import java.util.List;
import lombok.Data;/*** created on 2023/7/25 20:17** @author Dragonchu*/
@Data
public class OpenAiRequest {private String erp;private List<Message> messages;private String model;
}
package com.jd.jr.parrot.llm;import java.util.List;
import lombok.Data;/*** created on 2023/7/25 20:04** @author Dragonchu*/
@Data
public class OpenAiResponse {private long created;private Usage usage;private String model;private String id;private List<Choice> choices;private String object;
}

封装一个简单的工具,以供使用GPT

package com.jd.jr.parrot.llm;import com.google.gson.Gson;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.nio.charset.Charset;/*** created on 2023/7/25 20:07** @author Dragonchu*/
@Slf4j
public class LLMUtil {private static String url = "Your url";private static String apiKey = "Your key";public static String sendMsg(String msg){OpenAiRequest request = new OpenAiRequest();Message message = new Message();message.setRole("user");message.setContent(msg);request.setMessages(Arrays.asList(message));request.setModel("gpt-3.5-turbo");Gson gson = new Gson();String result = postGPT(url, gson.toJson(request));OpenAiResponse openAiResponse = gson.fromJson(result, OpenAiResponse.class);return openAiResponse.getChoices().get(0).getMessage().getContent();}/*** 发送 post 请求** @param url     请求地址* @param jsonStr Form表单json字符串* @return 请求结果*/public static String postGPT(String url, String jsonStr){// 创建httpClientCloseableHttpClient httpClient =HttpClients.createDefault();// 创建post请求方式实例HttpPost httpPost =newHttpPost(url);httpPost.setHeader("Content-type","application/json;charset=utf-8");httpPost.setHeader("Authorization", apiKey);// 设置参数---设置消息实体 也就是携带的数据StringEntity entity =newStringEntity(jsonStr,Charset.forName("UTF-8"));// 设置编码格式entity.setContentEncoding("UTF-8");// 发送Json格式的数据请求entity.setContentType("application/json");// 把请求消息实体塞进去httpPost.setEntity(entity);// 执行http的post请求CloseableHttpResponse httpResponse;String result =null;try{httpResponse = httpClient.execute(httpPost);result =EntityUtils.toString(httpResponse.getEntity(),"UTF-8");if(httpResponse.getStatusLine().getStatusCode()!=200){System.out.println("post->return error,result: "+ result);log.error("post->return error,result: {}", result);}}catch(IOException e){log.error("postStream->error", e);e.printStackTrace();}return result;}publicstaticvoidmain(String[] args){log.info(sendMsg("Who are you?"));}}

 


 

然后写一个Watcher

junit4提供了Rule机制,该机制利用AOP,使得我们可以在测试代码中嵌入相应的逻辑,比如在执行代码前输出方法名,捕获异常等。TestWatcher是一个抽象类,通过覆盖该类我们可以得到一个满足我们需求的Rule。

我们希望能在测试方法失败抛出异常后,直接将异常信息和异常堆栈发送给GPT,同时,也要将出错的代码文件发送给GPT(注意敏感信息哦,本文只是一个教程,请勿私自将敏感代码发送给GPT)。

简单写一个工具类,这个类封装了从异常堆栈中获取文件的能力。

package com.jd.jr.parrot;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** created on 2023/7/28 15:08** @author Dragonchu*/
public class ExceptionUtil {public static String getFileName(String stackTraceLine) {// 使用正则表达式提取文件名Pattern pattern = Pattern.compile("\\((.*\\.java)");Matcher matcher = pattern.matcher(stackTraceLine);if (matcher.find()) {String fileName = matcher.group(1);return fileName;}return null;}public static Path getPath(String stackTraceLine) {// 提取文件路径int firstParenthesisIndex = stackTraceLine.indexOf("(");int firstDotIndex = stackTraceLine.lastIndexOf(".", firstParenthesisIndex);String packagePath = stackTraceLine.substring(0, firstDotIndex).replace(".", File.separator);// 获取根路径String rootPath = new File("").getAbsolutePath();Path filePath = Paths.get(rootPath, "src", "main", "java", packagePath + ".java");return filePath;}publicstaticStringgetCodeFile(String stackTraceLine){Path filePath =getPath(stackTraceLine);if(filePath.toFile().exists()){// 读取文件内容try(BufferedReader reader =newBufferedReader(newFileReader(filePath.toFile()))){StringBuilder content =newStringBuilder();String line;while((line = reader.readLine())!=null){content.append(line).append("\n");}return content.toString();}catch(IOException e){e.printStackTrace();}}returnnull;}publicstaticvoidmain(String[] args){String stackTraceLine ="com.jd.jr.parrot.ExceptionExample.main(ExceptionExample.java:24)";String fileName =getFileName(stackTraceLine);System.out.println("fileName = "+ fileName);String path =getPath(stackTraceLine).toString();System.out.println("path = "+ path);String codeFile =getCodeFile(stackTraceLine);System.out.println("codeFile = "+ codeFile);}}

简单地设计一个prompt,也就是我们需要发给GPT的信息。

private static final String prompt = "\"You are a good Java engineer, please analyze the following error and provide possible solutions." +"The error message is : %s, The error stack is : %s. The code file is : %s";

当测试方法抛出异常后,我们将异常相关信息以及代码文件发送给GPT让它进行分析。

package com.jd.jr.parrot.junit;import com.jd.jr.parrot.ExceptionUtil;
import com.jd.jr.parrot.llm.LLMUtil;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;/*** created on 2023/7/28 14:07** @author Dragonchu*/
@Slf4j
public class OverWatch extends TestWatcher {private static final String prompt = "\"You are a good Java engineer, please analyze the following error and provide possible solutions." +"The error message is : %s, The error stack is : %s. The code file is : %s";@Overrideprotected void failed(Throwable e, Description description) {super.failed(e, description);String codeFile = ExceptionUtil.getCodeFile(e.getStackTrace()[0].toString());log.info(LLMUtil.sendMsg(String.format(prompt, e.getMessage(), Arrays.toString(e.getStackTrace()),codeFile)));}
}

让AI给我一份错误代码

本着能不自己干就不自己干的态度,我们让AI生成一份有错误的代码。

这是我与AI的对话:

我:

给我一份会抛出异常的代码,我希望这份代码稍微复杂一点,且依赖了一些外部包,它错误的原因比较难以排查。

AI:

以下是一个稍微复杂一点且依赖外部包的会抛出异常的Java代码示例:

📎importorg.jsoup.Jsoup;importorg.jsoup.nodes.Document;importorg.jsoup.nodes.Element;importorg.jsoup.select.Elements;importjava.io.IOException;publicclassExceptionExample{    publicstaticvoidmain(String[]args){        try{            // 使用Jsoup抓取网页内容            Documentdoc=Jsoup.connect("https://www.example.com").get();                        // 解析网页内容            Elementtitle=doc.select("title").first();            System.out.println("Title: "+title.text());                        // 尝试获取一个不存在的元素            ElementnonExistentElement=doc.select("#nonexistent-element").first();                        // 在非空元素上调用方法,会抛出NullPointerException            nonExistentElement.text();                    }catch(IOExceptione){            e.printStackTrace();        }    }}

这段代码使用外部包Jsoup来抓取网页内容并解析,然后尝试获取一个不存在的元素并在其上调用方法,会抛出NullPointerException异常。该异常可能比较难以排查,需要检查代码是否正确处理了异常情况,以及是否正确使用外部包的API等。

 

测试,让AI在junit测试失败后分析代码

简单写一个测试:

package com.jd.jr.parrot;import com.jd.jr.parrot.junit.OverWatch;
import java.io.IOException;
import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.MethodSorters;/*** created on 2023/7/28 14:14** @author Dragonchu*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OverWatchTest {@Rulepublic OverWatch overWatch = new OverWatch();@Testpublic void jsoupTest() throws IOException {ExceptionExample.main(new String[]{});}
}

测试结果

 

 

作者:京东科技 储惠龙

来源:京东云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/720946.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『vulnhub系列』HACKABLE-II

『vulnhub系列』HACKABLE-II 下载地址: https://www.vulnhub.com/entry/hackable-ii,711/信息搜集: 使用nmap探测存活主机,发现主机开启了21,22和80端口访问80端口的web服务,发现apache默认页面使用dirsearch进行目录爆破,发现files 目录 dirsearch -u "http://192.1…

电脑局域网内让其他电脑通过IP访问配置

依次点击桌面左下角“开始菜单”>“所有应用”>“Windows系统”>“控制面板”,如图所示 在控制面板界面,选择“查看方式”为“大图标”,然后点击打开window防火墙,如图所示 然后点击“高级设置”,如图所示在高级安全 Windows 防火墙界面,右侧点击Windows 防火墙…

.eslintrc-auto-import.json 自动导入 依赖 入ref reactive 等

.eslintrc-auto-import.json 自动导入 依赖 入ref reactive 等这篇文章比较详细介绍了这个,但是这种全局导入,其实也是酌情处理。 Reference: vite自动按需导入 https://blog.csdn.net/webbirds/article/details/127283504--------------------------------------------- 生…

13.56MHz电动车NFC刷卡解锁方案-SI522 SI512

随着电动车市场的快速发展,车主对车辆的智能化和便捷性的要求也在不断提升。仪表盘作为电动车的重要组成部分,不仅需要提供基本的行驶信息,还需要具备智能交互功能。基于13.56MHz频率的NFC(近场通信)技术为电动车仪表盘的智能化提供了有效解决方案。本文将介绍一种基于13.…

MBR10100FCT-ASEMI肖特基二极管MBR10100FCT

MBR10100FCT-ASEMI肖特基二极管MBR10100FCT编辑:ll MBR10100FCT-ASEMI肖特基二极管MBR10100FCT 型号:MBR10100FCT 品牌:ASEMI 封装:TO-220F 最大平均正向电流(IF):10A 最大循环峰值反向电压(VRRM):100V 最大正向电压(VF):0.80V 工作温度:-65C~175C 反向恢复时间:…

数字先锋 | “药”上云!天翼云助力国药数科加速建设“国药云”

5月25日,第七届数字中国建设峰会期间,“国云注智 聚力向新”——2024智算云生态大会智算云论坛在福州举办。会上,国药数科总经理助理、技术总监罗皓在演讲中介绍,国药数科携手天翼云,系统化构建“1+4+X国药云架构”,为各子公司提供统一标准的云底座、云联网、云运维、云灾…

企业级数据保护:华企盾DSC敏感内容识别与加密技术

在当今数字化时代,企业面临的数据安全挑战日益严峻。敏感数据的泄露不仅会导致经济损失,还可能损害企业的声誉和客户信任。因此,采用先进的敏感内容识别和加密技术,例如华企盾DSC敏感内容识别,对企业数据进行有效保护至关重要。一、敏感内容识别的重要性 企业内部的敏感数…

帆软BI对月累计值求年同比

新建计算字段:月累计值 DEF_ADD(SUM_AGG(${销售额}),[],[${年份}=EARLIER(${年份}),${月份}<=EARLIER(${月份})]) 新建计算字段:上一年月累计值DEF_ADD(SUM_AGG(${销售额}),[],[${年份}=EARLIER(${年份}-1),${月份}<=EARLIER(${月份})]) 新建计算字段:月累计值同比增长…

在线HMAC加密工具

在线HMAC加密工具提供一站式服务,支持MD5至SHA512、RIPEMD160及SM3等多种哈希算法,用户可便捷选择算法并生成安全的HMAC散列值,确保消息完整性与验证来源。适用于开发调试、网络安全测试及敏感数据处理场景。在线HMAC加密工具

利用西门子DQ模块控制移位寄存器,模拟串行通信

1. 背景以前了解过串行通信的方法但是没有详细了解过具体实现。趁着手上有的一堆破铜烂铁尝试自己去实现一个最简单的串行控制。 目的是通过移位寄存器的不同位的表达,达到2*2=4个的继电器管断组合,达到切换矩阵的目的。 这里只记录一下程序实现,不记录硬件电路。2. 材料移位…

利用西门子DQ模块控制移位寄存器的,模拟串行通信

1. 背景以前了解过串行通信的方法但是没有详细了解过具体实现。趁着手上有的一堆破铜烂铁尝试自己去实现一个最简单的串行控制。 目的是通过移位寄存器的不同位的表达,达到2*2=4个的继电器管断组合,达到切换矩阵的目的。 这里只记录一下程序实现,不记录硬件电路。2. 材料移位…

2024-06-06 前端开发环境

前言:今天公司给我配了台电脑,要我装一下环境,故此记录一下。 一.nvm:node版本管理器,全称Node Version Manage。使用它不用单独跑去node官网下载node,nvm提供了更便捷的下载方式。 下载链接:https://github.com/coreybutler/nvm-windows/releases上面两个任选一个即可。…