循环、轮询提交
This commit is contained in:
@@ -146,6 +146,11 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>2.8.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.test.common.core.domain.model;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:Jmeter调用参数
|
||||
* @date 2025-02-19 10:55
|
||||
*/
|
||||
public class JmeterRequest {
|
||||
/**
|
||||
* 用例步骤id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 请求完整url
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 请求端口号
|
||||
*/
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*/
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 请求body
|
||||
*/
|
||||
private String requestBody;
|
||||
|
||||
/**
|
||||
* 请求参数,url?后面的参数
|
||||
*/
|
||||
private String requestParams;
|
||||
|
||||
/**
|
||||
* 请求头Json
|
||||
*/
|
||||
private String requestHeader;
|
||||
|
||||
/**
|
||||
* jmeter安装home路径
|
||||
*/
|
||||
private String jmeterHomePath;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public String getRequestBody() {
|
||||
return requestBody;
|
||||
}
|
||||
|
||||
public void setRequestBody(String requestBody) {
|
||||
this.requestBody = requestBody;
|
||||
}
|
||||
|
||||
public String getRequestParams() {
|
||||
return requestParams;
|
||||
}
|
||||
|
||||
public void setRequestParams(String requestParams) {
|
||||
this.requestParams = requestParams;
|
||||
}
|
||||
|
||||
public String getRequestHeader() {
|
||||
return requestHeader;
|
||||
}
|
||||
|
||||
public void setRequestHeader(String requestHeader) {
|
||||
this.requestHeader = requestHeader;
|
||||
}
|
||||
|
||||
public String getJmeterHomePath() {
|
||||
return jmeterHomePath;
|
||||
}
|
||||
|
||||
public void setJmeterHomePath(String jmeterHomePath) {
|
||||
this.jmeterHomePath = jmeterHomePath;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package com.test.common.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import com.jayway.jsonpath.PathNotFoundException;
|
||||
import com.test.common.core.domain.model.JmeterRequest;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.config.gui.ArgumentsPanel;
|
||||
import org.apache.jmeter.control.LoopController;
|
||||
@@ -54,16 +57,18 @@ public class JMeterUtil {
|
||||
|
||||
/**
|
||||
* 生成jmeter测试执行计划并获取执行结果
|
||||
* @param id
|
||||
* @param url
|
||||
* @param port
|
||||
* @param method
|
||||
* @param paramJson
|
||||
* @param requestHeader
|
||||
* @param jmeterHomePath
|
||||
* @param jmeterRequest
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> getJmeterResult(Long id, String url, int port, String method, String paramJson, String requestHeader, String jmeterHomePath) {
|
||||
public static Map<String, String> getJmeterResult(JmeterRequest jmeterRequest) {
|
||||
Long id = jmeterRequest.getId();
|
||||
String url = jmeterRequest.getUrl();
|
||||
int port = jmeterRequest.getPort();
|
||||
String method = jmeterRequest.getMethod().toUpperCase();
|
||||
String requestBody = jmeterRequest.getRequestBody();
|
||||
String requestParams = jmeterRequest.getRequestParams();
|
||||
String requestHeader = jmeterRequest.getRequestHeader();
|
||||
String jmeterHomePath = jmeterRequest.getJmeterHomePath();
|
||||
Map<String, String> result = null;
|
||||
try {
|
||||
// 1. 初始化 JMeter
|
||||
@@ -83,13 +88,14 @@ public class JMeterUtil {
|
||||
httpSampler = createPostHttpSampler(
|
||||
url, // 请求地址
|
||||
port,
|
||||
paramJson // 请求参数
|
||||
requestBody, // 请求体
|
||||
requestParams // 查询参数
|
||||
);
|
||||
} else {
|
||||
httpSampler = createGetHttpSampler(
|
||||
url, // 请求地址
|
||||
port,
|
||||
paramJson // 请求参数
|
||||
requestParams // 查询参数
|
||||
);
|
||||
}
|
||||
// 5. 创建请求头管理器
|
||||
@@ -189,11 +195,11 @@ public class JMeterUtil {
|
||||
* 创建get请求方式
|
||||
* @param urlString
|
||||
* @param port
|
||||
* @param requestJson
|
||||
* @param requestParams
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static HTTPSamplerProxy createGetHttpSampler(String urlString, int port, String requestJson) throws MalformedURLException {
|
||||
private static HTTPSamplerProxy createGetHttpSampler(String urlString, int port, String requestParams) throws MalformedURLException {
|
||||
URL url = new URL(urlString);
|
||||
// 提取域名(不包括端口号)
|
||||
String domain = url.getHost();
|
||||
@@ -204,6 +210,9 @@ public class JMeterUtil {
|
||||
httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
|
||||
httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
|
||||
httpSampler.setDomain(domain); // 提取域名
|
||||
if (!StringUtils.isEmpty(requestParams)) {
|
||||
path = path + "?" + requestParams;
|
||||
}
|
||||
httpSampler.setPath(path); // 提取路径
|
||||
httpSampler.setPort(port);
|
||||
httpSampler.setMethod("GET");
|
||||
@@ -211,17 +220,17 @@ public class JMeterUtil {
|
||||
httpSampler.setUseKeepAlive(true);
|
||||
|
||||
// 添加请求参数
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
if (!StringUtils.isEmpty(requestJson)) {
|
||||
Gson gson = new Gson();
|
||||
// 定义 Map 的类型
|
||||
Type type = new TypeToken<Map<String, String>>() {}.getType();
|
||||
// 将 JSON 字符串转换为 Map
|
||||
parameters = gson.fromJson(requestJson, type);
|
||||
path += "?";
|
||||
path += mapToQueryString(parameters);
|
||||
httpSampler.setPath(path); // 提取路径
|
||||
}
|
||||
// Map<String, String> parameters = new HashMap<>();
|
||||
// if (!StringUtils.isEmpty(requestJson)) {
|
||||
// Gson gson = new Gson();
|
||||
// // 定义 Map 的类型
|
||||
// Type type = new TypeToken<Map<String, String>>() {}.getType();
|
||||
// // 将 JSON 字符串转换为 Map
|
||||
// parameters = gson.fromJson(requestJson, type);
|
||||
// path += "?";
|
||||
// path += mapToQueryString(parameters);
|
||||
// httpSampler.setPath(path); // 提取路径
|
||||
// }
|
||||
|
||||
return httpSampler;
|
||||
}
|
||||
@@ -249,11 +258,12 @@ public class JMeterUtil {
|
||||
* 创建post请求方式
|
||||
* @param urlString
|
||||
* @param port
|
||||
* @param requestJson
|
||||
* @param requestBody
|
||||
* @param requestParams
|
||||
* @return
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static HTTPSamplerProxy createPostHttpSampler(String urlString, int port, String requestJson) throws MalformedURLException {
|
||||
private static HTTPSamplerProxy createPostHttpSampler(String urlString, int port, String requestBody, String requestParams) throws MalformedURLException {
|
||||
URL url = new URL(urlString);
|
||||
// 提取域名(不包括端口号)
|
||||
String domain = url.getHost();
|
||||
@@ -265,15 +275,18 @@ public class JMeterUtil {
|
||||
httpSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
|
||||
httpSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());
|
||||
httpSampler.setDomain(domain);
|
||||
if (!StringUtils.isEmpty(requestParams)) {
|
||||
path = path + "?" + requestParams;
|
||||
}
|
||||
httpSampler.setPath(path);
|
||||
httpSampler.setPort(port);
|
||||
httpSampler.setMethod("POST");
|
||||
httpSampler.setConnectTimeout("5000");
|
||||
httpSampler.setUseKeepAlive(true);
|
||||
|
||||
// 设置请求头为 JSON
|
||||
// 设置请求体
|
||||
httpSampler.setPostBodyRaw(true); // 使用原始请求体
|
||||
httpSampler.addNonEncodedArgument("", requestJson, "");
|
||||
httpSampler.addNonEncodedArgument("", requestBody, "");
|
||||
|
||||
return httpSampler;
|
||||
}
|
||||
@@ -398,12 +411,21 @@ public class JMeterUtil {
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
Element httpSampleElement = (Element) httpSampleNode;
|
||||
String costMiliseconds = httpSampleElement.getAttribute("t");
|
||||
String responseCode = httpSampleElement.getAttribute("rc");
|
||||
resultMap.put("responseCode", responseCode);
|
||||
resultMap.put("costMiliseconds", costMiliseconds);
|
||||
// 提取子节点<responseData>的内容
|
||||
NodeList responseDataList = httpSampleElement.getElementsByTagName("responseData");
|
||||
if (responseDataList.getLength() > 0) {
|
||||
Element responseDataElement = (Element) responseDataList.item(0);
|
||||
resultMap.put("costMiliseconds", responseDataElement.getTextContent());
|
||||
resultMap.put("responseBody", responseDataElement.getTextContent());
|
||||
return resultMap;
|
||||
}
|
||||
// 提取子节点<responseHeader>的内容
|
||||
NodeList responseHeaderList = httpSampleElement.getElementsByTagName("responseHeader");
|
||||
if (responseHeaderList.getLength() > 0) {
|
||||
Element responseHeaderElement = (Element) responseHeaderList.item(0);
|
||||
resultMap.put("responseHeader", responseHeaderElement.getTextContent());
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
@@ -413,13 +435,56 @@ public class JMeterUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从响应头中读取Map信息结构
|
||||
* @param responseHeader
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, String> parseHeaders(String responseHeader) {
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
// 按行拆分
|
||||
String[] lines = responseHeader.split("\n");
|
||||
// 遍历每一行
|
||||
for (String line : lines) {
|
||||
// 忽略空行和 HTTP 状态行
|
||||
if (line.trim().isEmpty() || line.startsWith("HTTP/")) {
|
||||
continue;
|
||||
}
|
||||
// 按冒号拆分键值对
|
||||
int colonIndex = line.indexOf(":");
|
||||
if (colonIndex > 0) {
|
||||
String key = line.substring(0, colonIndex).trim();
|
||||
String value = line.substring(colonIndex + 1).trim();
|
||||
headerMap.put(key, value);
|
||||
}
|
||||
}
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 JSONPath 表达式从 JSON 中提取字段值
|
||||
*
|
||||
* @param json JSON 字符串
|
||||
* @param expression JSONPath 表达式
|
||||
* @return 字段值,如果字段不存在则返回 null
|
||||
*/
|
||||
public static String extractFieldValue(String json, String expression) {
|
||||
try {
|
||||
Object result = JsonPath.read(json, expression);
|
||||
return result != null ? result.toString() : null;
|
||||
} catch (PathNotFoundException e) {
|
||||
// 如果字段不存在,返回 null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String paramJson = "{\"md5Value\":\"value1\",\"fileName\":\"value2\"}";
|
||||
paramJson = "{\"name\":\"John\",\"city\":\"New York\",\"age\":30}";
|
||||
String requestHeader = "{\"Content-Type\":\"application/json; charset=UTF-8\",\"Authorization\":\"Bearer token123\"}";
|
||||
String jmeterHomePath = "D:/apache-jmeter-5.4.3";
|
||||
// String result = getJmeterResult("http://127.0.0.1:3000/api/items/add", 3000, "POST", paramJson, requestHeader, jmeterHomePath);
|
||||
getJmeterResult(123L, "http://127.0.0.1:3000/api/items/user", 3000, "GET", paramJson, requestHeader, jmeterHomePath);
|
||||
// getJmeterResult(123L, "http://127.0.0.1:3000/api/items/user", 3000, "GET", paramJson, requestHeader, jmeterHomePath);
|
||||
// System.out.println(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ public class TestCaseResult extends BaseEntity {
|
||||
/** http 响应体 */
|
||||
@Excel(name = "http 响应体")
|
||||
private String responseBody;
|
||||
|
||||
/** sql结果 */
|
||||
private String sqlResult;
|
||||
|
||||
/** 循环次 */
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:校验规则
|
||||
* @date 2025-02-19 17:33
|
||||
*/
|
||||
@Data
|
||||
public class AssertRule {
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 对象
|
||||
*/
|
||||
private String source;
|
||||
/**
|
||||
* 条件
|
||||
*/
|
||||
private String fn;
|
||||
/**
|
||||
* 比较值
|
||||
*/
|
||||
private String target;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:
|
||||
* @date 2025-02-19 21:02
|
||||
*/
|
||||
@Data
|
||||
public class AssertRuleResult extends AssertRule {
|
||||
/**
|
||||
* 实际值
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* 结果:通过;未通过
|
||||
*/
|
||||
private String result;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:提取规则
|
||||
* @date 2025-02-19 16:04
|
||||
*/
|
||||
@Data
|
||||
public class ExtractionRule {
|
||||
/**
|
||||
* 变量名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 提取方式
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 提取对象
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 提取表达式
|
||||
*/
|
||||
private String path;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.test.test.domain.qo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangdaliang
|
||||
* @Description:提取规则结果
|
||||
* @date 2025-02-19 16:12
|
||||
*/
|
||||
@Data
|
||||
public class ExtractionRuleResult extends ExtractionRule {
|
||||
/**
|
||||
* 提取结果
|
||||
*/
|
||||
private String value;
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.test.test.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.test.test.domain.TestCaseStep;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例步骤Mapper接口
|
||||
*
|
||||
@@ -58,4 +59,12 @@ public interface TestCaseStepMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseStepByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据用例id查询用例步骤列表并按照步骤顺序排序
|
||||
*
|
||||
* @param caseId 用例id
|
||||
* @return 用例步骤集合
|
||||
*/
|
||||
public List<TestCaseStep> selectTestCaseStepListByCaseId(Long caseId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestCaseLog;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例日志Service接口
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
public interface ITestCaseLogService
|
||||
{
|
||||
/**
|
||||
* 查询用例日志
|
||||
*
|
||||
* @param id 用例日志主键
|
||||
* @return 用例日志
|
||||
*/
|
||||
public TestCaseLog selectTestCaseLogById(Long id);
|
||||
|
||||
/**
|
||||
* 查询用例日志列表
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 用例日志集合
|
||||
*/
|
||||
public List<TestCaseLog> selectTestCaseLogList(TestCaseLog testCaseLog);
|
||||
|
||||
/**
|
||||
* 新增用例日志
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertTestCaseLog(TestCaseLog testCaseLog);
|
||||
|
||||
/**
|
||||
* 修改用例日志
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateTestCaseLog(TestCaseLog testCaseLog);
|
||||
|
||||
/**
|
||||
* 批量删除用例日志
|
||||
*
|
||||
* @param ids 需要删除的用例日志主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseLogByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除用例日志信息
|
||||
*
|
||||
* @param id 用例日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseLogById(Long id);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestCaseResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例执行报告Service接口
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
public interface ITestCaseResultService
|
||||
{
|
||||
/**
|
||||
* 查询用例执行报告
|
||||
*
|
||||
* @param id 用例执行报告主键
|
||||
* @return 用例执行报告
|
||||
*/
|
||||
public TestCaseResult selectTestCaseResultById(Long id);
|
||||
|
||||
/**
|
||||
* 查询用例执行报告列表
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 用例执行报告集合
|
||||
*/
|
||||
public List<TestCaseResult> selectTestCaseResultList(TestCaseResult testCaseResult);
|
||||
|
||||
/**
|
||||
* 新增用例执行报告
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertTestCaseResult(TestCaseResult testCaseResult);
|
||||
|
||||
/**
|
||||
* 修改用例执行报告
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateTestCaseResult(TestCaseResult testCaseResult);
|
||||
|
||||
/**
|
||||
* 批量删除用例执行报告
|
||||
*
|
||||
* @param ids 需要删除的用例执行报告主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseResultByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除用例执行报告信息
|
||||
*
|
||||
* @param id 用例执行报告主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseResultById(Long id);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.test.test.service;
|
||||
|
||||
import com.test.test.domain.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例Service接口
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
public interface ITestCaseService
|
||||
{
|
||||
/**
|
||||
* 查询用例
|
||||
*
|
||||
* @param id 用例主键
|
||||
* @return 用例
|
||||
*/
|
||||
public TestCase selectTestCaseById(Long id);
|
||||
|
||||
/**
|
||||
* 查询用例列表
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 用例集合
|
||||
*/
|
||||
public List<TestCase> selectTestCaseList(TestCase testCase);
|
||||
|
||||
/**
|
||||
* 新增用例
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertTestCase(TestCase testCase);
|
||||
|
||||
/**
|
||||
* 修改用例
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateTestCase(TestCase testCase);
|
||||
|
||||
/**
|
||||
* 批量删除用例
|
||||
*
|
||||
* @param ids 需要删除的用例主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除用例信息
|
||||
*
|
||||
* @param id 用例主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteTestCaseById(Long id);
|
||||
|
||||
/**
|
||||
* 执行用例计划
|
||||
*
|
||||
* @param id 用例主键id
|
||||
* @param jmeterHomePath jmeter安装路径
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean executeTestCaseById(Long id, String jmeterHomePath);
|
||||
}
|
||||
@@ -61,6 +61,14 @@ public interface ITestCaseStepService
|
||||
*/
|
||||
public int deleteTestCaseStepById(Long id);
|
||||
|
||||
/**
|
||||
* 根据用例id查询用例步骤列表并按照步骤顺序排序
|
||||
*
|
||||
* @param caseId 用例id
|
||||
* @return 用例步骤集合
|
||||
*/
|
||||
public List<TestCaseStep> selectTestCaseStepListByCaseId(Long caseId);
|
||||
|
||||
/**
|
||||
* 执行jmeter用例步骤计划
|
||||
*
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.test.test.service.impl;
|
||||
|
||||
import com.test.test.domain.TestCaseLog;
|
||||
import com.test.test.mapper.TestCaseLogMapper;
|
||||
import com.test.test.service.ITestCaseLogService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例日志Service业务层处理
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TestCaseLogServiceImpl implements ITestCaseLogService
|
||||
{
|
||||
@Resource
|
||||
private TestCaseLogMapper testCaseLogMapper;
|
||||
|
||||
/**
|
||||
* 查询用例日志
|
||||
*
|
||||
* @param id 用例日志主键
|
||||
* @return 用例日志
|
||||
*/
|
||||
@Override
|
||||
public TestCaseLog selectTestCaseLogById(Long id)
|
||||
{
|
||||
return testCaseLogMapper.selectTestCaseLogById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用例日志列表
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 用例日志
|
||||
*/
|
||||
@Override
|
||||
public List<TestCaseLog> selectTestCaseLogList(TestCaseLog testCaseLog)
|
||||
{
|
||||
return testCaseLogMapper.selectTestCaseLogList(testCaseLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用例日志
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTestCaseLog(TestCaseLog testCaseLog)
|
||||
{
|
||||
return testCaseLogMapper.insertTestCaseLog(testCaseLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用例日志
|
||||
*
|
||||
* @param testCaseLog 用例日志
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTestCaseLog(TestCaseLog testCaseLog)
|
||||
{
|
||||
return testCaseLogMapper.updateTestCaseLog(testCaseLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用例日志
|
||||
*
|
||||
* @param ids 需要删除的用例日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseLogByIds(Long[] ids)
|
||||
{
|
||||
return testCaseLogMapper.deleteTestCaseLogByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用例日志信息
|
||||
*
|
||||
* @param id 用例日志主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseLogById(Long id)
|
||||
{
|
||||
return testCaseLogMapper.deleteTestCaseLogById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.test.test.service.impl;
|
||||
|
||||
import com.test.test.domain.TestCaseResult;
|
||||
import com.test.test.mapper.TestCaseResultMapper;
|
||||
import com.test.test.service.ITestCaseResultService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用例执行报告Service业务层处理
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TestCaseResultServiceImpl implements ITestCaseResultService
|
||||
{
|
||||
@Resource
|
||||
private TestCaseResultMapper testCaseResultMapper;
|
||||
|
||||
/**
|
||||
* 查询用例执行报告
|
||||
*
|
||||
* @param id 用例执行报告主键
|
||||
* @return 用例执行报告
|
||||
*/
|
||||
@Override
|
||||
public TestCaseResult selectTestCaseResultById(Long id)
|
||||
{
|
||||
return testCaseResultMapper.selectTestCaseResultById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用例执行报告列表
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 用例执行报告
|
||||
*/
|
||||
@Override
|
||||
public List<TestCaseResult> selectTestCaseResultList(TestCaseResult testCaseResult)
|
||||
{
|
||||
return testCaseResultMapper.selectTestCaseResultList(testCaseResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用例执行报告
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTestCaseResult(TestCaseResult testCaseResult)
|
||||
{
|
||||
return testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用例执行报告
|
||||
*
|
||||
* @param testCaseResult 用例执行报告
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTestCaseResult(TestCaseResult testCaseResult)
|
||||
{
|
||||
return testCaseResultMapper.updateTestCaseResult(testCaseResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用例执行报告
|
||||
*
|
||||
* @param ids 需要删除的用例执行报告主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseResultByIds(Long[] ids)
|
||||
{
|
||||
return testCaseResultMapper.deleteTestCaseResultByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用例执行报告信息
|
||||
*
|
||||
* @param id 用例执行报告主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseResultById(Long id)
|
||||
{
|
||||
return testCaseResultMapper.deleteTestCaseResultById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
package com.test.test.service.impl;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.test.common.utils.DateUtils;
|
||||
import com.test.common.utils.JMeterUtil;
|
||||
import com.test.common.utils.StringUtils;
|
||||
import com.test.test.domain.TestCase;
|
||||
import com.test.test.domain.TestCaseResult;
|
||||
import com.test.test.domain.TestCaseStep;
|
||||
import com.test.test.domain.qo.AssertRule;
|
||||
import com.test.test.domain.qo.AssertRuleResult;
|
||||
import com.test.test.domain.qo.ExtractionRule;
|
||||
import com.test.test.domain.qo.ExtractionRuleResult;
|
||||
import com.test.test.mapper.TestCaseMapper;
|
||||
import com.test.test.mapper.TestCaseResultMapper;
|
||||
import com.test.test.service.ITestCaseService;
|
||||
import com.test.test.service.ITestCaseStepService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 用例Service业务层处理
|
||||
*
|
||||
* @author liangdl
|
||||
* @date 2025-02-18
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TestCaseServiceImpl implements ITestCaseService
|
||||
{
|
||||
@Resource
|
||||
private TestCaseMapper testCaseMapper;
|
||||
@Resource
|
||||
private TestCaseResultMapper testCaseResultMapper;
|
||||
|
||||
@Autowired
|
||||
private ITestCaseStepService testCaseStepService;
|
||||
|
||||
/**
|
||||
* 查询用例
|
||||
*
|
||||
* @param id 用例主键
|
||||
* @return 用例
|
||||
*/
|
||||
@Override
|
||||
public TestCase selectTestCaseById(Long id)
|
||||
{
|
||||
return testCaseMapper.selectTestCaseById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用例列表
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 用例
|
||||
*/
|
||||
@Override
|
||||
public List<TestCase> selectTestCaseList(TestCase testCase)
|
||||
{
|
||||
return testCaseMapper.selectTestCaseList(testCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用例
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertTestCase(TestCase testCase)
|
||||
{
|
||||
testCase.setCreateTime(DateUtils.getNowDate());
|
||||
return testCaseMapper.insertTestCase(testCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用例
|
||||
*
|
||||
* @param testCase 用例
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateTestCase(TestCase testCase)
|
||||
{
|
||||
testCase.setUpdateTime(DateUtils.getNowDate());
|
||||
return testCaseMapper.updateTestCase(testCase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用例
|
||||
*
|
||||
* @param ids 需要删除的用例主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseByIds(Long[] ids)
|
||||
{
|
||||
return testCaseMapper.deleteTestCaseByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用例信息
|
||||
*
|
||||
* @param id 用例主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteTestCaseById(Long id)
|
||||
{
|
||||
return testCaseMapper.deleteTestCaseById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行用例计划
|
||||
*
|
||||
* @param id 用例主键id
|
||||
* @param jmeterHomePath jmeter安装路径
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public boolean executeTestCaseById(Long id, String jmeterHomePath) {
|
||||
TestCase testCase = this.selectTestCaseById(id);
|
||||
if (testCase == null || "2".equals(testCase.getDelFlag())) {
|
||||
log.error("用例计划已被删除,不能执行!");
|
||||
return false;
|
||||
}
|
||||
List<TestCaseStep> testCaseStepList = testCaseStepService.selectTestCaseStepListByCaseId(id);
|
||||
for (TestCaseStep testCaseStep : testCaseStepList) {
|
||||
if (testCaseStep.getType() == 1L) {
|
||||
// http接口处理
|
||||
boolean httpTestResult = doHttpRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!httpTestResult) {
|
||||
log.error("用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
return false;
|
||||
}
|
||||
} else if (testCaseStep.getType() == 2L) {
|
||||
// 数据库接口处理
|
||||
} else if (testCaseStep.getType() == 3L) {
|
||||
// 循环节点处理
|
||||
boolean pollTestResult = doPollRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!pollTestResult) {
|
||||
log.error("循环用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
return false;
|
||||
}
|
||||
} else if (testCaseStep.getType() == 4L) {
|
||||
// 轮询节点处理
|
||||
boolean loopTestResult = doLoopRequestTest(testCase, testCaseStep, jmeterHomePath);
|
||||
if (!loopTestResult) {
|
||||
log.error("轮询用例步骤:{}执行失败!", testCaseStep.getName());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
log.error("错误的用例步骤类型!");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理http接口测试
|
||||
* @param testCase
|
||||
* @param testCaseStep
|
||||
* @param jmeterHomePath
|
||||
* @return 成功或失败
|
||||
*/
|
||||
private boolean doHttpRequestTest(TestCase testCase, TestCaseStep testCaseStep, String jmeterHomePath) {
|
||||
try {
|
||||
String assignment = testCaseStep.getAssignment(); // 参数提取
|
||||
String assertion = testCaseStep.getAssertion(); // 校验规则
|
||||
TestCaseResult testCaseResult = new TestCaseResult();
|
||||
testCaseResult.setExecuteTime(DateUtils.getNowDate());
|
||||
Map<String, String> resultMap = testCaseStepService.executeJmeterTestCaseStepById(testCaseStep.getId(), jmeterHomePath);
|
||||
testCaseResult.setCaseId(testCase.getId());
|
||||
testCaseResult.setStepId(testCaseStep.getId());
|
||||
if (resultMap != null) {
|
||||
testCaseResult.setResponseHeader(resultMap.get("responseHeader"));
|
||||
testCaseResult.setResponseBody(resultMap.get("responseBody"));
|
||||
// 处理参数提取
|
||||
Map<String, String> assignmentResultMap = new HashMap<>();
|
||||
String assignmentResult = this.dealTestCaseStepAssignment(resultMap, assignmentResultMap, assignment);
|
||||
testCaseResult.setAssignment(assignmentResult);
|
||||
// 根据提取结果处理校验规则
|
||||
String assertionResult = this.dealTestCaseStepAssertion(assignmentResultMap, assertion);
|
||||
testCaseResult.setAssertion(assertionResult);
|
||||
Long useTime = null;
|
||||
if (resultMap.get("useTime") != null) {
|
||||
useTime = Long.valueOf(resultMap.get("useTime"));
|
||||
}
|
||||
testCaseResult.setUseTime(useTime);
|
||||
if ("fail".equals(assignmentResultMap.get("assertionResult"))) {
|
||||
testCaseResult.setStatus("失败");
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return false;
|
||||
} else {
|
||||
testCaseResult.setStatus("成功");
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
}
|
||||
} else {
|
||||
testCaseResult.setAssignment(assignment);
|
||||
testCaseResult.setAssertion(assertion);
|
||||
testCaseResult.setUseTime(0L);
|
||||
testCaseResult.setStatus("失败");
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("HTTP请求测试发生异常: ", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理循环节点接口测试
|
||||
* @param testCase
|
||||
* @param testCaseStep
|
||||
* @param jmeterHomePath
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean doPollRequestTest(TestCase testCase, TestCaseStep testCaseStep, String jmeterHomePath) {
|
||||
try {
|
||||
// 先查出所有子节点测试步骤
|
||||
long pollCountCount = testCaseStep.getCount();
|
||||
Integer async = testCaseStep.getAsync();
|
||||
TestCaseResult testCaseResult = new TestCaseResult();
|
||||
testCaseResult.setExecuteTime(DateUtils.getNowDate());
|
||||
testCaseResult.setCaseId(testCase.getId());
|
||||
testCaseResult.setStepId(testCaseStep.getId());
|
||||
Long parentId = testCaseStep.getId();
|
||||
TestCaseStep testCaseStepInput = new TestCaseStep();
|
||||
testCaseStepInput.setCaseId(testCase.getId());
|
||||
testCaseStepInput.setParentId(parentId);
|
||||
testCaseStepInput.setDelFlag("0");
|
||||
List<TestCaseStep> testCaseStepChildList = testCaseStepService.selectTestCaseStepList(testCaseStepInput);
|
||||
long realPollCount = 1; // 实际循环次数
|
||||
boolean pollResult = true;
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < pollCountCount; i++) {
|
||||
for (TestCaseStep testCaseStepChild : testCaseStepChildList) {
|
||||
if (testCaseStepChild.getType() == 1L) {
|
||||
// http接口处理
|
||||
boolean httpTestResult = doHttpRequestTest(testCase, testCaseStepChild, jmeterHomePath);
|
||||
if (!httpTestResult) {
|
||||
log.error("子用例步骤:{}执行失败!", testCaseStepChild.getName());
|
||||
pollResult = false;
|
||||
break;
|
||||
}
|
||||
} else if (testCaseStepChild.getType() == 2L) {
|
||||
// 数据库接口处理
|
||||
}
|
||||
}
|
||||
if (!pollResult) {
|
||||
break;
|
||||
}
|
||||
realPollCount++;
|
||||
}
|
||||
testCaseResult.setUseTime(System.currentTimeMillis() - startTime);
|
||||
if (pollResult) {
|
||||
testCaseResult.setStatus("成功");
|
||||
testCaseResult.setPollingCount(realPollCount);
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return true;
|
||||
} else {
|
||||
testCaseResult.setStatus("失败");
|
||||
testCaseResult.setPollingCount(realPollCount);
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("循环节点测试发生异常: ", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理轮询节点接口测试
|
||||
* @param testCase
|
||||
* @param testCaseStep
|
||||
* @param jmeterHomePath
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean doLoopRequestTest(TestCase testCase, TestCaseStep testCaseStep, String jmeterHomePath) {
|
||||
try {
|
||||
// 先查出所有子节点测试步骤
|
||||
String breakError = testCaseStep.getBreakError();
|
||||
long interval = testCaseStep.getInterval() == null ? 0 : testCaseStep.getInterval();;
|
||||
long loopCountCount = testCaseStep.getCount();
|
||||
TestCaseResult testCaseResult = new TestCaseResult();
|
||||
testCaseResult.setExecuteTime(DateUtils.getNowDate());
|
||||
testCaseResult.setCaseId(testCase.getId());
|
||||
testCaseResult.setStepId(testCaseStep.getId());
|
||||
Long parentId = testCaseStep.getId();
|
||||
TestCaseStep testCaseStepInput = new TestCaseStep();
|
||||
testCaseStepInput.setCaseId(testCase.getId());
|
||||
testCaseStepInput.setParentId(parentId);
|
||||
testCaseStepInput.setDelFlag("0");
|
||||
List<TestCaseStep> testCaseStepChildList = testCaseStepService.selectTestCaseStepList(testCaseStepInput);
|
||||
long realLoopCount = 1; // 实际轮询次数
|
||||
boolean loopResult = false;
|
||||
long startTime = System.currentTimeMillis();
|
||||
int maxSize = testCaseStepChildList.size();
|
||||
for (int i = 0; i < loopCountCount; i++) {
|
||||
if (i > 0) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
} catch (InterruptedException e) {
|
||||
log.error("线程睡眠被中断: ", e);
|
||||
}
|
||||
}
|
||||
int index = 0;
|
||||
for (TestCaseStep testCaseStepChild : testCaseStepChildList) {
|
||||
if (testCaseStepChild.getType() == 1L) {
|
||||
// http接口处理
|
||||
boolean httpTestResult = doHttpRequestTest(testCase, testCaseStepChild, jmeterHomePath);
|
||||
if (!httpTestResult) {
|
||||
log.error("子用例步骤:{}执行失败!", testCaseStepChild.getName());
|
||||
break;
|
||||
}
|
||||
} else if (testCaseStepChild.getType() == 2L) {
|
||||
// 数据库接口处理
|
||||
}
|
||||
index ++;
|
||||
}
|
||||
realLoopCount ++;
|
||||
if (maxSize == index) {
|
||||
loopResult = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
testCaseResult.setUseTime(System.currentTimeMillis() - startTime);
|
||||
if (loopResult) {
|
||||
testCaseResult.setStatus("成功");
|
||||
testCaseResult.setLoopCount(realLoopCount);
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return true;
|
||||
} else {
|
||||
testCaseResult.setStatus("失败");
|
||||
testCaseResult.setLoopCount(realLoopCount);
|
||||
testCaseResultMapper.insertTestCaseResult(testCaseResult);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("轮询节点测试发生异常: ", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理响应字段提取
|
||||
* @param resultMap
|
||||
* @param assignmentResultMap
|
||||
* @param assignment
|
||||
* @return 处理后的提取结果
|
||||
*/
|
||||
private String dealTestCaseStepAssignment(Map<String, String> resultMap, Map<String, String> assignmentResultMap, String assignment) {
|
||||
String responseHeader = resultMap.get("responseHeader");
|
||||
String responseBody = resultMap.get("responseBody");
|
||||
String responseCode = resultMap.get("responseCode");
|
||||
if (!StringUtils.isEmpty(assignment) && !"[]".equals(assignment)) {
|
||||
Map<String, String> responseHeaderMap = JMeterUtil.parseHeaders(responseHeader);
|
||||
Gson gson = new Gson();
|
||||
Type ruleListType = new TypeToken<List<ExtractionRule>>() {}.getType();
|
||||
// 将 JSON 字符串解析为 List<ExtractionRule>
|
||||
List<ExtractionRule> rules = gson.fromJson(assignment, ruleListType);
|
||||
List<ExtractionRuleResult> ruleResultList = new ArrayList<>();
|
||||
for (ExtractionRule rule : rules) {
|
||||
ExtractionRuleResult ruleResult = new ExtractionRuleResult();
|
||||
BeanUtils.copyProperties(rule, ruleResult);
|
||||
String type = rule.getType();
|
||||
String content = rule.getContent();
|
||||
String path = rule.getPath();
|
||||
if ("${RESPONSE_BODY}".equals(content)) {
|
||||
if (type.startsWith("JSON")) {
|
||||
if (!path.startsWith("$.")) {
|
||||
path = "$." + path;
|
||||
}
|
||||
String value = JMeterUtil.extractFieldValue(responseBody, path);
|
||||
ruleResult.setValue(value);
|
||||
}
|
||||
} else if ("${RESPONSE_HEADER}".equals(content)) {
|
||||
String value = responseHeaderMap.get(path);
|
||||
ruleResult.setValue(value);
|
||||
} else if ("${RESPONSE_CODE}".equals(content)) {
|
||||
ruleResult.setValue(responseCode);
|
||||
}
|
||||
assignmentResultMap.put(rule.getName(), ruleResult.getValue());
|
||||
ruleResultList.add(ruleResult);
|
||||
}
|
||||
return gson.toJson(ruleResultList);
|
||||
} else {
|
||||
return assignment;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验测试用例步骤是否通过
|
||||
* @param assignmentResultMap
|
||||
* @param assertion
|
||||
* @return
|
||||
*/
|
||||
private String dealTestCaseStepAssertion(Map<String, String> assignmentResultMap, String assertion) {
|
||||
if (!StringUtils.isEmpty(assertion) && !"[]".equals(assertion)) {
|
||||
Gson gson = new Gson();
|
||||
Type ruleListType = new TypeToken<List<AssertRule>>() {}.getType();
|
||||
// 将 JSON 字符串解析为 List<AssertRule>
|
||||
List<AssertRule> rules = gson.fromJson(assertion, ruleListType);
|
||||
List<AssertRuleResult> ruleResultList = new ArrayList<>();
|
||||
for (AssertRule rule : rules) {
|
||||
AssertRuleResult ruleResult = new AssertRuleResult();
|
||||
BeanUtils.copyProperties(rule, ruleResult);
|
||||
String source = rule.getSource();
|
||||
String target = rule.getTarget();
|
||||
String fn = rule.getFn();
|
||||
String value = assignmentResultMap.get(source);
|
||||
ruleResult.setValue(value);
|
||||
if ("等于".equals(fn)) {
|
||||
if (target.equals(value)) {
|
||||
ruleResult.setResult("通过");
|
||||
} else {
|
||||
ruleResult.setResult("未通过");
|
||||
}
|
||||
} else if ("大于".equals(fn)) {
|
||||
int result = value.compareTo(target);
|
||||
if (result > 0) {
|
||||
ruleResult.setResult("通过");
|
||||
} else {
|
||||
ruleResult.setResult("未通过");
|
||||
}
|
||||
} else if ("小于".equals(fn)) {
|
||||
int result = value.compareTo(target);
|
||||
if (result < 0) {
|
||||
ruleResult.setResult("通过");
|
||||
} else {
|
||||
ruleResult.setResult("未通过");
|
||||
}
|
||||
} else {
|
||||
ruleResult.setResult("未通过");
|
||||
}
|
||||
if ("未通过".equals(ruleResult.getResult())) {
|
||||
assignmentResultMap.put("assertionResult", "fail");
|
||||
}
|
||||
ruleResultList.add(ruleResult);
|
||||
}
|
||||
return gson.toJson(ruleResultList);
|
||||
} else {
|
||||
return assertion;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.test.test.mapper.TestCaseResultMapper">
|
||||
|
||||
<resultMap type="TestCaseResult" id="TestCaseResultResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="caseId" column="case_id" />
|
||||
<result property="stepId" column="step_id" />
|
||||
<result property="responseHeader" column="response_header" />
|
||||
<result property="responseBody" column="response_body" />
|
||||
<result property="sqlResult" column="sql_result" />
|
||||
<result property="pollingCount" column="polling_count" />
|
||||
<result property="loopCount" column="loop_count" />
|
||||
<result property="assignment" column="assignment" />
|
||||
<result property="assertion" column="assertion" />
|
||||
<result property="useTime" column="use_time" />
|
||||
<result property="executeTime" column="execute_time" />
|
||||
<result property="status" column="status" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTestCaseResultVo">
|
||||
select id, case_id, step_id, response_header, response_body, sql_result, polling_count, loop_count, assignment, assertion, use_time, execute_time, status from test_case_result
|
||||
</sql>
|
||||
|
||||
<select id="selectTestCaseResultList" parameterType="TestCaseResult" resultMap="TestCaseResultResult">
|
||||
<include refid="selectTestCaseResultVo"/>
|
||||
<where>
|
||||
<if test="caseId != null "> and case_id = #{caseId}</if>
|
||||
<if test="stepId != null "> and step_id = #{stepId}</if>
|
||||
<if test="responseHeader != null and responseHeader != ''"> and response_header = #{responseHeader}</if>
|
||||
<if test="responseBody != null and responseBody != ''"> and response_body = #{responseBody}</if>
|
||||
<if test="sqlResult != null and sqlResult != ''"> and sql_result = #{sqlResult}</if>
|
||||
<if test="pollingCount != null "> and polling_count = #{pollingCount}</if>
|
||||
<if test="loopCount != null "> and loop_count = #{loopCount}</if>
|
||||
<if test="assignment != null and assignment != ''"> and assignment = #{assignment}</if>
|
||||
<if test="assertion != null and assertion != ''"> and assertion = #{assertion}</if>
|
||||
<if test="useTime != null "> and use_time = #{useTime}</if>
|
||||
<if test="executeTime != null "> and execute_time = #{executeTime}</if>
|
||||
<if test="status != null and status != ''"> and status = #{status}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectTestCaseResultById" parameterType="Long" resultMap="TestCaseResultResult">
|
||||
<include refid="selectTestCaseResultVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insertTestCaseResult" parameterType="TestCaseResult" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into test_case_result
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="caseId != null">case_id,</if>
|
||||
<if test="stepId != null">step_id,</if>
|
||||
<if test="responseHeader != null">response_header,</if>
|
||||
<if test="responseBody != null">response_body,</if>
|
||||
<if test="sqlResult != null">sql_result,</if>
|
||||
<if test="pollingCount != null">polling_count,</if>
|
||||
<if test="loopCount != null">loop_count,</if>
|
||||
<if test="assignment != null">assignment,</if>
|
||||
<if test="assertion != null">assertion,</if>
|
||||
<if test="useTime != null">use_time,</if>
|
||||
<if test="executeTime != null">execute_time,</if>
|
||||
<if test="status != null">status,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="caseId != null">#{caseId},</if>
|
||||
<if test="stepId != null">#{stepId},</if>
|
||||
<if test="responseHeader != null">#{responseHeader},</if>
|
||||
<if test="responseBody != null">#{responseBody},</if>
|
||||
<if test="sqlResult != null">#{sqlResult},</if>
|
||||
<if test="pollingCount != null">#{pollingCount},</if>
|
||||
<if test="loopCount != null">#{loopCount},</if>
|
||||
<if test="assignment != null">#{assignment},</if>
|
||||
<if test="assertion != null">#{assertion},</if>
|
||||
<if test="useTime != null">#{useTime},</if>
|
||||
<if test="executeTime != null">#{executeTime},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateTestCaseResult" parameterType="TestCaseResult">
|
||||
update test_case_result
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="caseId != null">case_id = #{caseId},</if>
|
||||
<if test="stepId != null">step_id = #{stepId},</if>
|
||||
<if test="responseHeader != null">response_header = #{responseHeader},</if>
|
||||
<if test="responseBody != null">response_body = #{responseBody},</if>
|
||||
<if test="sqlResult != null">sql_result = #{sqlResult},</if>
|
||||
<if test="pollingCount != null">polling_count = #{pollingCount},</if>
|
||||
<if test="loopCount != null">loop_count = #{loopCount},</if>
|
||||
<if test="assignment != null">assignment = #{assignment},</if>
|
||||
<if test="assertion != null">assertion = #{assertion},</if>
|
||||
<if test="useTime != null">use_time = #{useTime},</if>
|
||||
<if test="executeTime != null">execute_time = #{executeTime},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteTestCaseResultById" parameterType="Long">
|
||||
delete from test_case_result where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteTestCaseResultByIds" parameterType="String">
|
||||
delete from test_case_result where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -67,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="assignment != null and assignment != ''"> and assignment = #{assignment}</if>
|
||||
<if test="assertion != null and assertion != ''"> and assertion = #{assertion}</if>
|
||||
</where>
|
||||
ORDER BY step_num
|
||||
</select>
|
||||
|
||||
<select id="selectTestCaseStepById" parameterType="Long" resultMap="TestCaseStepResult">
|
||||
@@ -183,4 +184,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="selectTestCaseStepListByCaseId" parameterType="Long" resultMap="TestCaseStepResult">
|
||||
<include refid="selectTestCaseStepVo"/>
|
||||
where case_id = #{caseId} and del_flag = '0' and parent_id is null
|
||||
ORDER BY step_num
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user