自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Junit4遇上ChatGPT,會擦出什么火花!

人工智能
簡單的通過AI,讓它基于json格式生成相應(yīng)的類文件,這樣方便我們在代碼中使用,而不用顯示寫json字符串。

這是一篇適合Java工程師體質(zhì)的AI開發(fā)教程。

本教程會教你寫一個簡單的junit4的Rule,該Rule在基于junit4的測試方法失敗后,自動向GPT發(fā)送錯誤信息并通過GPT分析得出代碼修改建議。

首先向AI問好

簡單的通過AI,讓它基于json格式生成相應(yīng)的類文件,這樣方便我們在代碼中使用,而不用顯示寫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();
    }


    /**
     * 發(fā)送 post 請求
     *
     * @param url     請求地址
     * @param jsonStr Form表單json字符串
     * @return 請求結(jié)果
     */
    public static String postGPT(String url, String jsonStr) {
        // 創(chuàng)建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 創(chuàng)建post請求方式實例
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-type", "application/json;charset=utf-8");
        httpPost.setHeader("Authorization", apiKey);


        // 設(shè)置參數(shù)---設(shè)置消息實體 也就是攜帶的數(shù)據(jù)
        StringEntity entity = new StringEntity(jsonStr, Charset.forName("UTF-8"));
        // 設(shè)置編碼格式
        entity.setContentEncoding("UTF-8");
        // 發(fā)送Json格式的數(shù)據(jù)請求
        entity.setContentType("application/json");
        // 把請求消息實體塞進去
        httpPost.setEntity(entity);
        // 執(zhí)行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;
    }


    public static void main(String[] args) {
        log.info(sendMsg("Who are you?"));
    }


}

圖片

然后寫一個Watcher

junit4提供了Rule機制,該機制利用AOP,使得我們可以在測試代碼中嵌入相應(yīng)的邏輯,比如在執(zhí)行代碼前輸出方法名,捕獲異常等。TestWatcher是一個抽象類,通過覆蓋該類我們可以得到一個滿足我們需求的Rule。

我們希望能在測試方法失敗拋出異常后,直接將異常信息和異常堆棧發(fā)送給GPT,同時,也要將出錯的代碼文件發(fā)送給GPT(注意敏感信息哦,本文只是一個教程,請勿私自將敏感代碼發(fā)送給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;
    }


    public static String getCodeFile(String stackTraceLine) {
        Path filePath = getPath(stackTraceLine);
        if (filePath.toFile().exists()) {
            // 讀取文件內(nèi)容
            try (BufferedReader reader = new BufferedReader(new FileReader(filePath.toFile()))) {
                StringBuilder content = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    content.append(line).append("\n");
                }
                return content.toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    public static void main(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);
    }
}

簡單地設(shè)計一個prompt,也就是我們需要發(fā)給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";

當(dāng)測試方法拋出異常后,我們將異常相關(guān)信息以及代碼文件發(fā)送給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";


    @Override
    protected 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給我一份錯誤代碼:

本著能不自己干就不自己干的態(tài)度,我們讓AI生成一份有錯誤的代碼。

這是我與AI的對話:

我:

給我一份會拋出異常的代碼,我希望這份代碼稍微復(fù)雜一點,且依賴了一些外部包,它錯誤的原因比較難以排查。

AI:

以下是一個稍微復(fù)雜一點且依賴外部包的會拋出異常的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抓取網(wǎng)頁內(nèi)容            Documentdoc=Jsoup.connect("https://www.example.com").get();                        // 解析網(wǎng)頁內(nèi)容            Elementtitle=doc.select("title").first();            System.out.println("Title: "+title.text());                        // 嘗試獲取一個不存在的元素            Elementnnotallow=doc.select("#nonexistent-element").first();                        // 在非空元素上調(diào)用方法,會拋出NullPointerException            nonExistentElement.text();                    }catch(IOExceptione){            e.printStackTrace();        }    }}

這段代碼使用外部包Jsoup來抓取網(wǎng)頁內(nèi)容并解析,然后嘗試獲取一個不存在的元素并在其上調(diào)用方法,會拋出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 {
    @Rule
    public OverWatch overWatch = new OverWatch();


    @Test
    public void jsoupTest() throws IOException {
        ExceptionExample.main(new String[]{});
    }
}

測試結(jié)果:

圖片圖片

責(zé)任編輯:武曉燕 來源: 京東云開發(fā)者
相關(guān)推薦

2018-11-12 13:27:12

教育區(qū)塊鏈學(xué)習(xí)

2015-06-30 15:18:04

2020-08-17 17:16:21

5G網(wǎng)絡(luò)技術(shù)

2023-03-11 00:16:08

2022-08-29 20:13:28

物聯(lián)網(wǎng)IPV6

2021-03-11 14:28:07

云計算云原生邊緣計算

2021-03-11 22:39:06

VRAR虛擬現(xiàn)實技術(shù)

2018-08-07 09:38:06

2016-10-18 11:10:12

存儲

2009-12-03 13:32:04

Virtuozzo捆綁

2011-12-26 10:38:28

JavaJUnitRule

2011-12-26 10:49:27

JavaJUnitRunner

2018-09-26 20:01:17

金融大數(shù)據(jù)數(shù)據(jù)平臺

2018-06-05 13:33:16

SDN5GNFV

2017-09-03 07:34:52

2015-06-04 14:48:09

CIO時代網(wǎng)

2017-11-14 05:38:54

2012-09-26 09:45:19

大數(shù)據(jù)在線旅游

2022-10-20 08:00:37

機器人ZadigChatOps
點贊
收藏

51CTO技術(shù)棧公眾號