AI测试用例生成方法封装

This commit is contained in:
even 2025-07-23 09:46:02 +08:00
parent cb6cbb069f
commit 87b96c6ddd
7 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,11 @@
package cd.casic.ci.process.constant;
/**
* AI测试用例生成url常量类
* */
public class TestCaseAIGeneratorConstant {
public static final String targetUpload ="/upload-target";
public static final String taskCreate ="/create-task";
public static final String getTaskStatus ="/query-task/";
public static final String getTaskLog ="/task-log/";
public static final String downloadTestCase ="/download-case/";
}

View File

@ -0,0 +1,13 @@
package cd.casic.ci.process.dto.req.testCase;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.zip.ZipOutputStream;
@Data
public class TestCaseAITargetUploadReq {
private String binaryPath;
private MultipartFile file;
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.process.dto.req.testCase;
import lombok.Data;
/**
* {
* "model_id": "gpt-4", // 可选模型ID默认值为deepseek/deepseekchat
* "api_key": "your-api-key", // 可选API密钥
* "api_base": "https://api.openai.com/v1", // 可选API基础URL默认值为
* https://api.deepseek.com
* "binary_id": "abc123def456", // 条件可选二进制文件ID, 如果未提供则需要提供
* case_format参数
* "case_format": "png", // 条件可选测试用例文件格式, 如果未提供则需要提
* 供binary_id参数
* "custom_prompt": "", // 可选测试用例生成任务的自定义提示词, "构造
* 尽可能小的png文件"
* "count": 10 // 可选生成用例数量默认10
* }
* */
@Data
public class TestCaseAITaskCreateReq {
private String binaryId;
private String caseFormat;
private String customPrompt;
private Integer count;
}

View File

@ -0,0 +1,22 @@
package cd.casic.ci.process.process.service.testCase;
import cd.casic.ci.process.dto.req.testCase.TestCaseAITargetUploadReq;
import cd.casic.ci.process.dto.req.testCase.TestCaseAITaskCreateReq;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public interface TestCaseAIGeneratorService {
/**
* 目标文件上传
* */
public String targetUpload(String binaryPath, InputStream inputStream) throws IOException;
/**
* 创建测试用例生成任务
* */
public String taskCreate(TestCaseAITaskCreateReq req);
public String getTaskStatus(String taskId);
public String getTaskLog(String taskId);
public void downloadTestCase(String taskId, OutputStream outputStream) throws IOException;
}

View File

@ -0,0 +1,106 @@
package cd.casic.ci.process.process.service.testCase.impl;
import cd.casic.ci.process.constant.TestCaseAIGeneratorConstant;
import cd.casic.ci.process.dto.req.testCase.TestCaseAITargetUploadReq;
import cd.casic.ci.process.dto.req.testCase.TestCaseAITaskCreateReq;
import cd.casic.ci.process.process.service.testCase.TestCaseAIGeneratorService;
import cd.casic.ci.process.properties.TestCaseAIProperties;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.util.IOUtils;
import jakarta.annotation.Resource;
import net.schmizz.sshj.transport.kex.ECDHNistP;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.HashMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@Service
public class TestCaseAIGeneratorServiceImpl implements TestCaseAIGeneratorService {
@Resource
private TestCaseAIProperties properties;
@Resource
private RestTemplate restTemplate;
@Override
public String targetUpload(String binaryPath, InputStream inputStream) throws IOException {
File tempFile = File.createTempFile("target", ".zip");
tempFile.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tempFile);
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry entry = new ZipEntry(tempFile.getName());
zos.putNextEntry(entry);
IOUtils.copy(inputStream,zos);
zos.closeEntry();
inputStream.close();
FileSystemResource fsr = new FileSystemResource(tempFile);
String url = properties.getBaseUrl()+ TestCaseAIGeneratorConstant.targetUpload;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String,Object> body = new LinkedMultiValueMap<>();
body.add("file",fsr);
body.add("binary_path",binaryPath);
HttpEntity<MultiValueMap<String,Object>> entity = new HttpEntity<>(body,headers);
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, entity, String.class, new HashMap<>());
return exchange.getBody();
}
@Override
public String taskCreate(TestCaseAITaskCreateReq req) {
if (StringUtils.hasLength(req.getBinaryId()) &&StringUtils.hasLength(req.getCaseFormat())) {
return "";
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("binary_id",req.getBinaryId());
jsonObject.put("count",req.getCount());
jsonObject.put("custom_prompt",req.getCustomPrompt());
jsonObject.put("case_format",req.getCaseFormat());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(jsonObject),headers);
String url = properties.getBaseUrl() + TestCaseAIGeneratorConstant.taskCreate;
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, entity, String.class, new HashMap<>());
return exchange.getBody();
}
@Override
public String getTaskStatus(String taskId) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{}",headers);
String url = properties.getBaseUrl() + TestCaseAIGeneratorConstant.getTaskStatus+taskId;
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, new HashMap<>());
return exchange.getBody();
}
@Override
public String getTaskLog(String taskId) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{}",headers);
String url = properties.getBaseUrl() + TestCaseAIGeneratorConstant.getTaskLog+taskId;
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, new HashMap<>());
return exchange.getBody();
}
@Override
public void downloadTestCase(String taskId, OutputStream outputStream) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{}",headers);
String url = properties.getBaseUrl() + TestCaseAIGeneratorConstant.downloadTestCase+taskId;
ResponseEntity<InputStream> exchange = restTemplate.exchange(url, HttpMethod.GET, entity, InputStream.class, new HashMap<>());
IOUtils.copy(exchange.getBody(),outputStream);
}
}

View File

@ -0,0 +1,12 @@
package cd.casic.ci.process.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "test-case.ai")
@Component
@Data
public class TestCaseAIProperties {
private String baseUrl;
}

View File

@ -1,4 +1,5 @@
package cd.casic.server;
import cd.casic.module.machine.utils.CryptogramUtil;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;