Commit 40055ffd authored by 黎博's avatar 黎博

Merge branch 'master' into jira

parents 5e68af09 18dbe672
...@@ -25,7 +25,7 @@ public class InterceptorConfig implements WebMvcConfigurer { ...@@ -25,7 +25,7 @@ public class InterceptorConfig implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(yeebaoInterceptor()).addPathPatterns("/mock/tzt-api/**", "/mock/balance-board/**"); registry.addInterceptor(yeebaoInterceptor()).addPathPatterns("/tzt-api/**", "/balance-board/**");
registry.addInterceptor(ruleEngineInterceptor()).addPathPatterns("/rule_engine/**"); registry.addInterceptor(ruleEngineInterceptor()).addPathPatterns("/rule_engine/**");
} }
} }
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.AutoModule;
import cn.qg.holmes.service.auto.AutoModuleService;
import cn.qg.holmes.service.auto.AutoProjectService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 接口自动化模块controller
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/module")
public class AutoModuleController {
@Autowired
AutoModuleService autoModuleService;
@Autowired
AutoProjectService autoProjectService;
/**
* 获取接口自动化模块列表
* @param pageNum 第几页
* @param pageSize 每页第几个
* @return
*/
@GetMapping("/list")
public JsonResult getAutoModuleList(Integer pageNum, Integer pageSize) {
IPage<AutoModule> autoModuleIPage = autoModuleService.getAutoModuleList(pageNum, pageSize);
Map<String, Object> map = new HashMap<>();
map.put("total", autoModuleIPage.getTotal());
map.put("list", autoModuleIPage.getRecords());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增模块
* @param autoModule AutoModule实体类
* @return
*/
@PostMapping("/add")
public JsonResult addAutoModule(@RequestBody AutoModule autoModule) {
QueryWrapper<AutoModule> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", autoModule.getName());
if (autoProjectService.getById(autoModule.getProjectId()) == null) {
return JsonResult.buildErrorStateResult("所选项目不存在!", false);
} else if (autoModuleService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("模块已存在!", false);
} else {
return JsonResult.buildSuccessResult(autoModuleService.save(autoModule));
}
}
/**
* 修改模块
* @param autoModule AutoModule实体类
* @return
*/
@PostMapping("/modify")
public JsonResult editAutoModule(@RequestBody AutoModule autoModule) {
QueryWrapper<AutoModule> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", autoModule.getName());
queryWrapper.ne("id", autoModule.getId());
if (autoModuleService.getById(autoModule.getId()) == null) {
return JsonResult.buildErrorStateResult("模块不存在!", false);
} else if (autoModuleService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("该模块名已存在!", false);
} else {
return JsonResult.buildSuccessResult(autoModuleService.updateById(autoModule));
}
}
/**
* 删除模块
* @param moduleId 模块id
*/
@GetMapping("/delete")
public JsonResult deleteAutoModule(@RequestParam Integer moduleId) {
if (autoModuleService.getById(moduleId) == null) {
return JsonResult.buildErrorStateResult("模块不存在", false);
} else {
return JsonResult.buildSuccessResult(autoModuleService.removeById(moduleId));
}
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.AutoProject;
import cn.qg.holmes.service.auto.AutoProjectService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 接口自动化项目相关controller
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/project")
public class AutoProjectController {
@Autowired
AutoProjectService autoProjectService;
/**
* 获取项目列表
* @param pageNum 第几页
* @param pageSize 每页数量
* @return
*/
@GetMapping("/list")
public JsonResult getAutoProjectList(@RequestParam Integer pageNum, @RequestParam Integer pageSize) {
IPage<AutoProject> projectIPage = new Page<>(pageNum, pageSize);
IPage<AutoProject> projectPageEntity = autoProjectService.page(projectIPage);
Map<String, Object> map = new HashMap<>();
map.put("list", projectPageEntity.getRecords());
map.put("total", projectPageEntity.getTotal());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增项目
* @param autoProject 项目实体
* @return
*/
@PostMapping("/add")
public JsonResult autoProjectAdd(@RequestBody AutoProject autoProject) {
// 判断项目是否已存在
QueryWrapper<AutoProject> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", autoProject.getName());
if (autoProjectService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("该名称项目已存在!", false);
} else {
return JsonResult.buildSuccessResult(autoProjectService.save(autoProject));
}
}
/**
* 修改项目
* @param autoProject 项目实体
* @return
*/
@PostMapping("/modify")
public JsonResult autoProjectModify(@RequestBody AutoProject autoProject) {
if (autoProjectService.getById(autoProject.getId()) == null) {
return JsonResult.buildErrorStateResult("项目不存在", false);
} else {
return JsonResult.buildSuccessResult(autoProjectService.updateById(autoProject));
}
}
/**
* 删除项目
* @param projectId 项目id
*/
@GetMapping("/delete")
public JsonResult autoProjectDelete(@RequestParam Integer projectId) {
if (autoProjectService.getById(projectId) == null) {
return JsonResult.buildErrorStateResult("该项目不存在!", false);
} else {
return JsonResult.buildSuccessResult(autoProjectService.removeById(projectId));
}
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.Interface;
import cn.qg.holmes.service.auto.AutoModuleService;
import cn.qg.holmes.service.auto.InterfaceService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 接口相关controller
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/interface")
public class InterfaceController {
@Autowired
InterfaceService interfaceService;
@Autowired
AutoModuleService autoModuleService;
/**
* 获取接口列表
* @param moduleId 非必传
* @param pageNum 第几页
* @param pageSize 每页数量
* @return
*/
@GetMapping("/list")
public JsonResult getInterfaceList(Integer moduleId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
IPage<Interface> interfaceIPage = new Page<>(pageNum, pageSize);
IPage<Interface> interfaceIPageEntity;
if (moduleId != null) {
QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("module_id", moduleId);
interfaceIPageEntity = interfaceService.page(interfaceIPage, queryWrapper);
} else {
interfaceIPageEntity = interfaceService.page(interfaceIPage);
}
Map<String, Object> map = new HashMap<>();
map.put("total", interfaceIPageEntity.getTotal());
map.put("list", interfaceIPageEntity.getRecords());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增接口
* @param interfaceEntity 接口类实体
* @return
*/
@PostMapping("/add")
public JsonResult addInterface(@RequestBody Interface interfaceEntity) {
QueryWrapper<Interface> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("module_id", interfaceEntity.getModuleId());
queryWrapper.eq("url", interfaceEntity.getUrl());
if (autoModuleService.getById(interfaceEntity.getModuleId()) == null) {
return JsonResult.buildErrorStateResult("模块不存在!", false);
}
if (interfaceService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("接口已存在!", false);
} else {
return JsonResult.buildSuccessResult(interfaceService.save(interfaceEntity));
}
}
/**
* 编辑接口
* @param interfaceEntity 接口实体类
* @return
*/
@PostMapping("/modify")
public JsonResult modifyInterface(@RequestBody Interface interfaceEntity) {
if (interfaceService.getById(interfaceEntity.getId()) == null) {
return JsonResult.buildErrorStateResult("接口不存在!", false);
}
return JsonResult.buildSuccessResult(interfaceService.updateById(interfaceEntity));
}
/**
* 删除接口
* @param interfaceId 接口id
* @return
*/
@GetMapping("/delete")
public JsonResult deleteInterface(@RequestParam Integer interfaceId) {
if (interfaceService.getById(interfaceId) == null) {
return JsonResult.buildErrorStateResult("接口不存在!", false);
}
return JsonResult.buildSuccessResult(interfaceService.removeById(interfaceId));
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.Scene;
import cn.qg.holmes.service.auto.AutoProjectService;
import cn.qg.holmes.service.auto.SceneService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 场景相关接口
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/scene")
public class SceneController {
@Autowired
SceneService sceneService;
@Autowired
AutoProjectService autoProjectService;
/**
* 获取场景列表
* @param pageNum 第几页
* @param pageSize 每页多少个
* @return
*/
@GetMapping("/list")
public JsonResult getSceneList(Integer projectId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
IPage<Scene> page = new Page<>(pageNum, pageSize);
IPage<Scene> sceneIPage;
if (projectId == null) {
sceneIPage = sceneService.page(page);
} else {
QueryWrapper<Scene> sceneQueryWrapper = new QueryWrapper<>();
sceneQueryWrapper.eq("project_id", projectId);
sceneIPage = sceneService.page(page, sceneQueryWrapper);
}
Map<String, Object> map = new HashMap<>();
map.put("list", sceneIPage.getRecords());
map.put("total", sceneIPage.getTotal());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增场景
* @param scene 场景实体
* @return
*/
@PostMapping("/add")
public JsonResult addScene(@RequestBody Scene scene) {
if (scene.getProjectId() == null) {
return JsonResult.buildErrorStateResult("项目不允许为空!", false);
}
if (scene.getName() == null) {
JsonResult.buildErrorStateResult("场景名不允许为空!", false);
}
if (autoProjectService.getById(scene.getProjectId()) == null) {
return JsonResult.buildErrorStateResult("项目不存在!", false);
}
return JsonResult.buildSuccessResult(sceneService.save(scene));
}
/**
* 修改场景
* @param scene 场景实体
* @return
*/
@PostMapping("/modify")
public JsonResult modifyScene(@RequestBody Scene scene) {
if (scene.getId() == null) {
return JsonResult.buildErrorStateResult("场景id不能为空!", false);
}
if (autoProjectService.getById(scene.getProjectId()) == null) {
return JsonResult.buildErrorStateResult("项目不存在!", false);
}
return JsonResult.buildSuccessResult(sceneService.updateById(scene));
}
/**
* 删除场景
* @param sceneId 场景id
* @return
*/
@GetMapping("/delete")
public JsonResult deleteScene(Integer sceneId) {
if (sceneService.getById(sceneId) == null) {
return JsonResult.buildErrorStateResult("场景不存在!", false);
}
return JsonResult.buildSuccessResult(sceneService.removeById(sceneId));
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.SceneTestcase;
import cn.qg.holmes.service.auto.SceneTestcaseService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@CrossOrigin
@RestController
@RequestMapping("/auto/sceneTestcase")
public class SceneTestcaseController {
@Autowired
SceneTestcaseService sceneTestcaseService;
/**
* 获取场景用例列表
* @param projectId 项目id,不传表示获取所有项目场景用例
* @param pageNum 第几页
* @param pageSize 每页展示多少个
* @return
*/
@GetMapping("/list")
public JsonResult getSceneTestcaseList(Integer projectId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
IPage<SceneTestcase> sceneTestcaseIPage = sceneTestcaseService.getSceneTestcaseList(projectId, pageNum, pageSize);
Map<String, Object> map = new HashMap<>();
map.put("total", sceneTestcaseIPage.getTotal());
map.put("list", sceneTestcaseIPage.getRecords());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增场景用例
* @param sceneTestcaseList 场景用例列表
* @return
*/
@PostMapping("/add")
public JsonResult addSceneTestcase(@RequestBody List<SceneTestcase> sceneTestcaseList) {
// 首先查询表里是否已有相应的数据
for (SceneTestcase sceneTestcase: sceneTestcaseList) {
if (sceneTestcase.getSceneId() == null) {
return JsonResult.buildErrorStateResult("场景id不能为空!", false);
}
if (sceneTestcase.getSequence() == null) {
return JsonResult.buildErrorStateResult("用例顺序不能为空!", false);
}
if (sceneTestcase.getInterfaceId() == null) {
return JsonResult.buildErrorStateResult("接口id不能为空!", false);
}
QueryWrapper<SceneTestcase> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("scene_id", sceneTestcase.getSceneId());
queryWrapper.eq("sequence", sceneTestcase.getSequence());
if (sceneTestcaseService.getOne(queryWrapper) != null) {
return JsonResult.buildErrorStateResult("场景用例已存在!", false);
}
}
for (SceneTestcase sceneTestcase: sceneTestcaseList) {
sceneTestcaseService.save(sceneTestcase);
}
return JsonResult.buildSuccessResult(true);
}
/**
* 批量修改场景用例列表
* @param sceneTestcaseList 场景用例列表
* @return
*/
@PostMapping("/modify")
public JsonResult modifySceneTestcase(@RequestBody List<SceneTestcase> sceneTestcaseList) {
return JsonResult.buildSuccessResult(sceneTestcaseService.updateBatchById(sceneTestcaseList));
}
/**
* 删除单个场景用例
* @param sceneTestcaseId 单个场景用例id
* @return
*/
@GetMapping("/delete")
public JsonResult deleteSceneTestcase(@RequestParam Integer sceneTestcaseId) {
if (sceneTestcaseService.getById(sceneTestcaseId) == null) {
return JsonResult.buildErrorStateResult("场景用例不存在!", false);
}
return JsonResult.buildSuccessResult(sceneTestcaseService.removeById(sceneTestcaseId));
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.AutoModule;
import cn.qg.holmes.entity.auto.Scene;
import cn.qg.holmes.entity.auto.Testcase;
import cn.qg.holmes.service.auto.AutoModuleService;
import cn.qg.holmes.service.auto.SceneService;
import cn.qg.holmes.service.auto.SceneTestcaseService;
import cn.qg.holmes.service.auto.TestcaseService;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* 测试用例执行controller
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/execute")
public class TestExecutionController {
@Autowired
TestcaseService testcaseService;
@Autowired
SceneTestcaseService sceneTestcaseService;
@Autowired
SceneService sceneService;
@Autowired
AutoModuleService autoModuleService;
/**
* 执行单个用例
* @param namespace 环境
* @param testcaseId 用例id
* @return
*/
@GetMapping("/testcase")
public JsonResult executeSingleTestcase(@RequestParam String namespace, @RequestParam Integer testcaseId) {
Testcase testcase = testcaseService.getById(testcaseId);
String testcaseName = testcase.getName();
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SS");
String batch = dateFormat.format(date) + "_" + testcaseName;
return JsonResult.buildSuccessResult(JSON.parseObject(testcaseService.singleTestcaseExecutor(namespace, testcaseId, batch), Map.class));
}
/**
* 执行一个模块下所有用例
* @param namespace 环境
* @param moduleId 模块id
* @return
*/
@GetMapping("/module")
public JsonResult executeTestcaseByModule(@RequestParam String namespace, @RequestParam Integer moduleId) {
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SS");
AutoModule autoModule = autoModuleService.getById(moduleId);
String moduleName = autoModule.getName();
String batch = dateFormat.format(date) + "_" + moduleName;
return JsonResult.buildSuccessResult(JSON.parseArray(testcaseService.executeTestcaseByModuleId(namespace, moduleId, batch)));
}
/**
* 执行场景用例
* @param namespace 环境
* @param sceneId 场景id
* @return
*/
@GetMapping("/scene")
public JsonResult executeSceneTestcase(String namespace, Integer sceneId) {
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SS");
Scene scene = sceneService.getById(sceneId);
String batch = dateFormat.format(date) + "_" + scene.getName();
return JsonResult.buildSuccessResult(JSON.parseArray(sceneTestcaseService.executeSceneTestcase(namespace, sceneId, batch)));
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.SceneTestcaseReport;
import cn.qg.holmes.entity.auto.TestcaseReport;
import cn.qg.holmes.service.auto.SceneTestcaseReportService;
import cn.qg.holmes.service.auto.TestcaseReportService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 测试报告相关接口
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/report")
public class TestReportController {
@Autowired
TestcaseReportService testcaseReportService;
@Autowired
SceneTestcaseReportService sceneTestcaseReportService;
/**
* 根据namespace和模块id获取单接口用例batch列表
* @param namespace 环境
* @param moduleId 模块id
* @param pageNum 第几页
* @param pageSize 每页多少个
* @return
*/
@GetMapping("/testcase/batch/list")
public JsonResult getTestcaseReportBatchList(String namespace, Integer moduleId, Integer pageNum, Integer pageSize) {
IPage<Map<String, Object>> mapIPage = testcaseReportService.getTestcaseReportGroupByBatch(namespace, moduleId, pageNum, pageSize);
Map<String, Object> map = new HashMap<>();
map.put("total", mapIPage.getTotal());
map.put("list", mapIPage.getRecords());
return JsonResult.buildSuccessResult(map);
}
/**
* 根据环境和项目id获取场景batch列表
* @param namespace 环境
* @param projectId 项目id
* @param pageNum 第几页
* @param pageSize 每页多少个
* @return
*/
@GetMapping("/scene/batch/list")
public JsonResult getSceneTestcaseReportBatchList(String namespace, Integer projectId, @RequestParam Integer pageNum, @RequestParam Integer pageSize) {
IPage<Map<String, Object>> sceneTestcaseReportIPage = sceneTestcaseReportService.getSceneTestcaseReportGroupByBatch(namespace, projectId, pageNum, pageSize);
Map<String, Object> map = new HashMap<>();
map.put("total", sceneTestcaseReportIPage.getTotal());
map.put("list", sceneTestcaseReportIPage.getRecords());
return JsonResult.buildSuccessResult(map);
}
@GetMapping("/testcase/list")
public JsonResult getTestcaseReportListByNamespace(String namespace,
Integer projectId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return JsonResult.buildSuccessResult(testcaseReportService.getTestcaseReportByNamespace(namespace, projectId, pageNum, pageSize));
}
@GetMapping("/scene/list")
public JsonResult getSceneTestcaseReportListByNamespace(String namespace,
Integer moduleId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return JsonResult.buildSuccessResult(sceneTestcaseReportService.getSceneTestcaseReportListByNamespace(namespace, moduleId, pageNum, pageSize));
}
/**
* 获取testcase batch详情列表
* @param namespace 环境
* @param batch batch名
* @return
*/
@GetMapping("/testcase/batch/detail")
public JsonResult getTestcaseReportBatchDetail(String namespace, String batch) {
if (batch == null || batch.isEmpty()) {
return JsonResult.buildErrorStateResult("batch不能为空!", false);
}
if (namespace == null || namespace.isEmpty()) {
return JsonResult.buildErrorStateResult("namespace不能为空!", false);
}
QueryWrapper<TestcaseReport> testcaseReportQueryWrapper = new QueryWrapper<>();
testcaseReportQueryWrapper.eq("namespace", namespace);
testcaseReportQueryWrapper.eq("batch", batch);
List<TestcaseReport> testcaseReports = testcaseReportService.list(testcaseReportQueryWrapper);
return JsonResult.buildSuccessResult(testcaseReports);
}
/**
* 获取场景batch详情列表
* @param namespace 环境
* @param batch batch名
* @return
*/
@GetMapping("/scene/batch/detail")
public JsonResult getSceneReportBatchDetail(String namespace, String batch) {
if (batch == null || batch.isEmpty()) {
return JsonResult.buildErrorStateResult("batch不能为空!", false);
}
if (namespace == null || namespace.isEmpty()) {
return JsonResult.buildErrorStateResult("namespace不能为空!", false);
}
QueryWrapper<SceneTestcaseReport> sceneTestcaseReportQueryWrapper = new QueryWrapper<>();
sceneTestcaseReportQueryWrapper.eq("namespace", namespace);
sceneTestcaseReportQueryWrapper.eq("batch", batch);
List<SceneTestcaseReport> sceneTestcaseReports = sceneTestcaseReportService.list(sceneTestcaseReportQueryWrapper);
return JsonResult.buildSuccessResult(sceneTestcaseReports);
}
}
package cn.qg.holmes.controller.auto;
import cn.qg.holmes.common.JsonResult;
import cn.qg.holmes.entity.auto.Testcase;
import cn.qg.holmes.service.auto.TestcaseService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* 用例相关接口
* @author libo
*/
@CrossOrigin
@RestController
@RequestMapping("/auto/testcase")
public class TestcaseController {
@Autowired
TestcaseService testcaseService;
/**
* 获取单接口用例列表
* @param moduleId 模块id
* @param pageNum 第几页
* @param pageSize 每页数量
* @return
*/
@GetMapping("/list")
public JsonResult getTestcaseList(Integer moduleId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
IPage<Testcase> page = new Page<>(pageNum, pageSize);
IPage<Testcase> testcaseIPageEntity;
if (moduleId != null) {
QueryWrapper<Testcase> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("module_id", moduleId);
testcaseIPageEntity = testcaseService.page(page, queryWrapper);
} else {
testcaseIPageEntity = testcaseService.page(page);
}
Map<String, Object> map = new HashMap<>();
map.put("total", testcaseIPageEntity.getTotal());
map.put("list", testcaseIPageEntity.getRecords());
return JsonResult.buildSuccessResult(map);
}
/**
* 新增单接口用例
* @param testcase
* @return
*/
@PostMapping("/add")
public JsonResult addTestcase(@RequestBody Testcase testcase) {
if (testcase.getName() == null || testcase.getInterfaceId() == null || testcase.getModuleId() == null) {
return JsonResult.buildErrorStateResult("用例名称、接口、所属模块不能为空!", false);
} else {
return JsonResult.buildSuccessResult(testcaseService.save(testcase));
}
}
/**
* 编辑单接口用例
* @param testcase 单接口用例实体
* @return
*/
@PostMapping("/modify")
public JsonResult modifyTestcase(@RequestBody Testcase testcase) {
if (testcase.getId() == null) {
return JsonResult.buildErrorStateResult("用例id不能为空!", false);
} else {
return JsonResult.buildSuccessResult(testcaseService.updateById(testcase));
}
}
/**
* 删除测试用例
* @param testcaseId 用例id
* @return
*/
@GetMapping("/delete")
public JsonResult deleteTestcase(@RequestParam Integer testcaseId) {
if (testcaseService.getById(testcaseId) == null) {
return JsonResult.buildErrorStateResult("用例不存在!", false);
} else {
return JsonResult.buildSuccessResult(testcaseService.removeById(testcaseId));
}
}
}
...@@ -15,6 +15,10 @@ import org.springframework.web.bind.annotation.*; ...@@ -15,6 +15,10 @@ import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* Mock相关controller
* @author libo
*/
@Slf4j @Slf4j
@CrossOrigin @CrossOrigin
@RestController @RestController
......
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 接口自动化-模块实体类
* @author libo
*/
@TableName(value = "auto_module")
@Data
public class AutoModule {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String description;
private String domain;
private Integer projectId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
@TableField(exist = false)
private String projectName;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 项目实体类
* @author libo
*/
@Data
public class AutoProject {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String description;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 接口实体类
* @author libo
*/
@Data
public class Interface {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String url;
private String method;
private String headers;
private String paramType;
private String paramTemplate;
private String responseTemplate;
private Integer moduleId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 场景实体类
* @author libo
*/
@Data
@TableName("scene")
public class Scene {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer projectId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 场景用例实体类
* @author libo
*/
@Data
@TableName("scene_testcase")
public class SceneTestcase {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer sceneId;
private Integer interfaceId;
private String preAction;
private String postAction;
private String headers;
private String parameters;
private String variables;
private String extract;
private String validate;
private Integer sequence;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 场景用例报告
* @author libo
*/
@TableName(value = "scene_testcase_report")
@Data
public class SceneTestcaseReport {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer sceneId;
private Integer sceneTestcaseId;
private String url;
private String headers;
private String parameters;
private String response;
private String validate;
private String status;
private Long elapsedTime;
private Integer sequence;
private String batch;
private Integer projectId;
private String namespace;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 单接口用例实体类
* @author libo
*/
@TableName("testcase")
@Data
public class Testcase {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private Integer interfaceId;
private String preAction;
private String postAction;
private String headers;
private String parameters;
private String variables;
private String extract;
private String validate;
private Integer moduleId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
package cn.qg.holmes.entity.auto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 测试报告实体类
* @author libo
*/
@TableName(value = "testcase_report")
@Data
public class TestcaseReport {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer testcaseId;
private String url;
private String headers;
private String parameters;
private String response;
private String validate;
private String status;
private Long elapsedTime;
private String batch;
private Integer moduleId;
private String namespace;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
...@@ -56,14 +56,17 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -56,14 +56,17 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
if (mock.getFlag() == 1) { if (mock.getFlag() == 1) {
mockData = mock.getSuccess(); mockData = mock.getSuccess();
} }
log.info("收到风控接口 {} 请求,请求参数:{}", uri, requestMap);
if (uri.equals("/rule_engine/middle_office/audit")) { if (uri.equals("/rule_engine/middle_office/audit")) {
Map<String, Object> auditMap = JSON.parseObject(mockData, Map.class); Map<String, Object> auditMap = JSON.parseObject(mockData, Map.class);
Map<String, Object> responseMap = handleRiskAudit(requestMap, auditMap); Map<String, Object> responseMap = handleRiskAudit(requestMap, auditMap);
log.info("/rule_engine/middle_office/audit的mock响应为:{}", responseMap);
InterceptorUtils.constructResponse(response, JSON.toJSONString(responseMap), "application/json; charset=utf-8"); InterceptorUtils.constructResponse(response, JSON.toJSONString(responseMap), "application/json; charset=utf-8");
return false; return false;
} }
log.info("{}的mock响应为:{}", uri, mockData);
InterceptorUtils.constructResponse(response, mockData, "application/json; charset=utf-8"); InterceptorUtils.constructResponse(response, mockData, "application/json; charset=utf-8");
return true; return false;
} }
/** /**
...@@ -116,7 +119,7 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -116,7 +119,7 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
// vcc // vcc
String callbackUrl = requestMap.get("callbackUrl").toString(); String callbackUrl = requestMap.get("callbackUrl").toString();
if (callbackUrl.contains("talos")) { if (callbackUrl.contains("talos")) {
vccRiskAuthAmountCompletion(callbackUrl, bizChannel, uuid, bizNo, (Integer) auditData.get("vccAuditAmount"), (Boolean) auditData.get("vccAuditResult")); vccRiskAuthAmountCompletion(callbackUrl, bizChannel, uuid, bizNo, auditData.get("vccAuditAmount").toString(), auditData.get("vccAuditResult").toString());
} }
// 一单一审现金贷 // 一单一审现金贷
if (bizType.equals("0")) { if (bizType.equals("0")) {
...@@ -135,7 +138,7 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -135,7 +138,7 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
} }
// vcc账单分期审核, sceneId=11 // vcc账单分期审核, sceneId=11
if (bizType.equals("8") && sceneId.equals("11")) { if (bizType.equals("8") && sceneId.equals("11")) {
bodyMap.put("allowInstalment", 1); bodyMap.put("allowInstalment", "1");
bodyMap.put("allowInstalmentTerms", "3,6,9,12"); bodyMap.put("allowInstalmentTerms", "3,6,9,12");
} }
// vcc支付限额审核, sceneId=12 // vcc支付限额审核, sceneId=12
...@@ -156,13 +159,12 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -156,13 +159,12 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception { @Nullable ModelAndView modelAndView) {
log.info("本次请求返回响应:{}", response);
} }
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception { @Nullable Exception ex) {
} }
/** /**
...@@ -174,41 +176,41 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -174,41 +176,41 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
* @param amount 授信金额 * @param amount 授信金额
* @param auditResult 授信结果,true/false * @param auditResult 授信结果,true/false
*/ */
public static void vccRiskAuthAmountCompletion(String callbackUrl,String bizChannel, String uuid, String riskNo, Integer amount, boolean auditResult) { public static void vccRiskAuthAmountCompletion(String callbackUrl,String bizChannel, String uuid, String riskNo, String amount, String auditResult) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 15); calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 15);
long openingDeadLine = calendar.getTimeInMillis(); Long openingDeadLine = calendar.getTimeInMillis();
Calendar calendar2 = Calendar.getInstance(); Calendar calendar2 = Calendar.getInstance();
calendar2.add(Calendar.YEAR, 1); calendar2.add(Calendar.YEAR, 1);
Long deadLine = calendar2.getTimeInMillis(); Long deadLine = calendar2.getTimeInMillis();
Map<String, Object> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("amount", amount); params.put("amount", amount);
params.put("auditResult", auditResult); params.put("auditResult", auditResult);
params.put("bizChannel", bizChannel); params.put("bizChannel", bizChannel);
params.put("bizNo", riskNo); params.put("bizNo", riskNo);
params.put("code", 0); params.put("code", "0");
params.put("deadLine", deadLine); params.put("deadLine", deadLine.toString());
params.put("openingDeadLine", openingDeadLine); // 开户失败有效期 params.put("openingDeadLine", String.valueOf(openingDeadLine)); // 开户失败有效期
params.put("success", true); params.put("success", "true");
params.put("uuid", uuid); params.put("uuid", uuid);
params.put("sceneId", 0); params.put("sceneId", "0");
params.put("allowInstalment", 1); // 1-允许分期,0-不允许分期 params.put("allowInstalment", "1"); // 1-允许分期,0-不允许分期
params.put("allowInstalmentTerms", "3,6,9,12"); // 允许分期的期数 params.put("allowInstalmentTerms", "3,6,9,12"); // 允许分期的期数
Map<String, Object> headers = new HashMap<>(); Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded"); headers.put("Content-Type", "application/x-www-form-urlencoded");
JSONObject result = HttpClientUtils.doPost(callbackUrl, params, headers); String result = HttpClientUtils.doPost(callbackUrl, headers, params);
log.info("vcc风控授信回调参数:{}", params); log.info("vcc风控授信回调参数:{}", params);
log.info("vcc风控授信回调结果:{}", result); log.info("vcc风控授信回调结果:{}", result);
} }
public static void quotaAuthAmountAuditNotify(String callbackUrl, String uuid, Integer bizChannel, Integer fundId, String bizNo, Integer bizType, Integer creditAmount, Integer term, boolean auditResult) { public static void quotaAuthAmountAuditNotify(String callbackUrl, String uuid, String bizChannel, String fundId, String bizNo, String bizType, String creditAmount, String term, String auditResult) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 30); calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 30);
Long deadLine = calendar.getTimeInMillis(); Long deadLine = calendar.getTimeInMillis();
Map<String, Object> headers = new HashMap<>(); Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded"); headers.put("Content-Type", "application/x-www-form-urlencoded");
Map<String, Object> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("code", 0); params.put("code", "0");
params.put("msg", "success"); params.put("msg", "success");
params.put("bizChannel", bizChannel); // 渠道号 params.put("bizChannel", bizChannel); // 渠道号
params.put("uuid", uuid); params.put("uuid", uuid);
...@@ -216,16 +218,16 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -216,16 +218,16 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
params.put("bizType", bizType); // 业务类型: 0-现金分期一单一审,…… params.put("bizType", bizType); // 业务类型: 0-现金分期一单一审,……
params.put("auditResult", auditResult); params.put("auditResult", auditResult);
params.put("amount", creditAmount); params.put("amount", creditAmount);
params.put("deadLine", deadLine); params.put("deadLine", String.valueOf(deadLine));
params.put("extData", ""); params.put("extData", "");
params.put("otherInformation", ""); params.put("otherInformation", "");
JSONArray financeProducts = createFinanceProducts(fundId, term); JSONArray financeProducts = createFinanceProducts(fundId, term);
params.put("financeProducts", financeProducts); params.put("financeProducts", JSONArray.toJSONString(financeProducts));
HttpClientUtils.doPost(callbackUrl, params, headers); HttpClientUtils.doPost(callbackUrl, headers, params);
log.info("现金分期风控授信回调:{}", params); log.info("现金分期风控授信回调:{}", params);
} }
public static JSONArray createFinanceProducts(Integer fundId, Integer term) { public static JSONArray createFinanceProducts(String fundId, String term) {
JSONArray financeProducts = new JSONArray(); JSONArray financeProducts = new JSONArray();
JSONObject financeProductsObject = new JSONObject(); JSONObject financeProductsObject = new JSONObject();
JSONArray terms = new JSONArray(); JSONArray terms = new JSONArray();
...@@ -241,11 +243,11 @@ public class RuleEngineInterceptor implements HandlerInterceptor { ...@@ -241,11 +243,11 @@ public class RuleEngineInterceptor implements HandlerInterceptor {
fundInfoObject.put("priority", 1); fundInfoObject.put("priority", 1);
fundInfoObject.put("feeType", 1); fundInfoObject.put("feeType", 1);
// 如果是云南信托,需要该参数 // 如果是云南信托,需要该参数
if (fundId == 1040) { if (fundId.equals("1040")) {
fundInfoObject.put("fundProductId", 1061); fundInfoObject.put("fundProductId", 1061);
} }
// 平顶山银行 // 平顶山银行
if (fundId == 1030) { if (fundId.equals("1030")) {
fundInfoObject.put("fundProductId", 1060); fundInfoObject.put("fundProductId", 1060);
} }
fundInfoList.add(fundInfoObject); fundInfoList.add(fundInfoObject);
......
...@@ -39,7 +39,7 @@ public class YeebaoInterceptor implements HandlerInterceptor { ...@@ -39,7 +39,7 @@ public class YeebaoInterceptor implements HandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { throws Exception {
String uri = request.getRequestURI().substring(5); String uri = request.getRequestURI();
Map<String, String[]> parameterMap = request.getParameterMap(); Map<String, String[]> parameterMap = request.getParameterMap();
QueryWrapper<Mock> queryWrapper = new QueryWrapper<>(); QueryWrapper<Mock> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("url", uri); queryWrapper.eq("url", uri);
...@@ -63,6 +63,7 @@ public class YeebaoInterceptor implements HandlerInterceptor { ...@@ -63,6 +63,7 @@ public class YeebaoInterceptor implements HandlerInterceptor {
if (mock.getEncrypt() == 1) { if (mock.getEncrypt() == 1) {
EncryptConvertor encryptConvertor = EncryptFactory.produce("yeebao"); EncryptConvertor encryptConvertor = EncryptFactory.produce("yeebao");
requestMap = JSON.parseObject(encryptConvertor.decrypt(JSON.toJSONString(convertParameterMap(parameterMap))), Map.class); requestMap = JSON.parseObject(encryptConvertor.decrypt(JSON.toJSONString(convertParameterMap(parameterMap))), Map.class);
log.info("收到{}接口请求,解密后的请求参数为:{}", request.getRequestURI(), requestMap);
// 判断返回是字符串还是json,1-json,2-字符串 // 判断返回是字符串还是json,1-json,2-字符串
if (mock.getType() == 1) { if (mock.getType() == 1) {
responseMap = disposeResponseMap(requestMap, responseMap); responseMap = disposeResponseMap(requestMap, responseMap);
...@@ -76,37 +77,42 @@ public class YeebaoInterceptor implements HandlerInterceptor { ...@@ -76,37 +77,42 @@ public class YeebaoInterceptor implements HandlerInterceptor {
if (uri.equals("/tzt-api/api/bindcard/confirm") && mock.getFlag() == 1) { if (uri.equals("/tzt-api/api/bindcard/confirm") && mock.getFlag() == 1) {
responseMap = handleBindCardConfirm(requestMap, responseMap); responseMap = handleBindCardConfirm(requestMap, responseMap);
} }
log.info("{}接口返回的响应为:{}", request.getRequestURI(), responseMap);
constructResponse(response, encryptConvertor.encrypt(JSON.toJSONString(responseMap)), "application/json; charset=utf-8"); constructResponse(response, encryptConvertor.encrypt(JSON.toJSONString(responseMap)), "application/json; charset=utf-8");
} else if (mock.getType() == 2) { } else if (mock.getType() == 2) {
log.info("{}接口返回的响应为:{}", request.getRequestURI(), responseStr);
constructResponse(response, encryptConvertor.encrypt(responseStr)); constructResponse(response, encryptConvertor.encrypt(responseStr));
} }
} else if (mock.getEncrypt() == 0) { } else if (mock.getEncrypt() == 0) {
requestMap = convertParameterMap(parameterMap); requestMap = convertParameterMap(parameterMap);
log.info("收到{}接口请求,请求参数为:{}", request.getRequestURI(), requestMap);
if (mock.getType() == 1) { if (mock.getType() == 1) {
responseMap = disposeResponseMap(requestMap, responseMap); responseMap = disposeResponseMap(requestMap, responseMap);
log.info("{}接口返回的响应为:{}", request.getRequestURI(), responseMap);
constructResponse(response, JSON.toJSONString(responseMap), "application/json; charset=utf-8"); constructResponse(response, JSON.toJSONString(responseMap), "application/json; charset=utf-8");
} else if (mock.getType() == 2) { } else if (mock.getType() == 2) {
// 针对 /balance-board/transfer 接口特殊处理 // 针对 /balance-board/transfer 接口特殊处理
if (uri.equals("/balance-board/transfer")) { if (uri.equals("/balance-board/transfer")) {
responseStr = handleBalanceBoardTransfer(request); responseStr = handleBalanceBoardTransfer(request);
log.info("{}接口返回的响应为:{}", request.getRequestURI(), responseStr);
constructResponse(response, responseStr); constructResponse(response, responseStr);
return false; return false;
} }
log.info("{}接口返回的响应为:{}", request.getRequestURI(), responseStr);
constructResponse(response, responseStr); constructResponse(response, responseStr);
} }
} }
return true; return false;
} }
@Override @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception { @Nullable ModelAndView modelAndView) {
log.info("本次请求返回响应:{}", response);
} }
@Override @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception { @Nullable Exception ex) {
} }
/** /**
......
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.AutoModule;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
public interface AutoModuleMapper extends BaseMapper<AutoModule> {
IPage<AutoModule> getAutoModuleList(IPage<AutoModule> page);
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.AutoProject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface AutoProjectMapper extends BaseMapper<AutoProject> {
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.Interface;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface InterfaceMapper extends BaseMapper<Interface> {
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.Scene;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface SceneMapper extends BaseMapper<Scene> {
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.SceneTestcase;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
public interface SceneTestcaseMapper extends BaseMapper<SceneTestcase> {
IPage<SceneTestcase> getSceneTestcaseList(Integer projectId, IPage<SceneTestcase> page);
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.SceneTestcaseReport;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.Map;
public interface SceneTestcaseReportMapper extends BaseMapper<SceneTestcaseReport> {
IPage<Map<String, Object>> getSceneTestcaseReportGroupByBatch(String namespace, Integer projectId, IPage<Map<String, Object>> page);
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.Testcase;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface TestcaseMapper extends BaseMapper<Testcase> {
}
package cn.qg.holmes.mapper.auto;
import cn.qg.holmes.entity.auto.TestcaseReport;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.Map;
public interface TestcaseReportMapper extends BaseMapper<TestcaseReport> {
IPage<Map<String, Object>> getTestcaseReportGroupByBatch(String namespace, Integer moduleId, IPage<Map<String, Object>> page);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.AutoModule;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface AutoModuleService extends IService<AutoModule> {
IPage<AutoModule> getAutoModuleList(Integer pageNum, Integer pageSize);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.AutoProject;
import com.baomidou.mybatisplus.extension.service.IService;
public interface AutoProjectService extends IService<AutoProject> {
}
package cn.qg.holmes.service.auto;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public interface AutoUtilsService {
Map<String, String> replaceHeaders(String headers, String variables, UUID uuid);
Map<String, String> replaceParameters(String parameters, String variables, UUID uuid);
boolean extractResponse(String response, String extract, UUID uuid);
boolean assertResponse(String response, List<Map> validateList);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.Interface;
import com.baomidou.mybatisplus.extension.service.IService;
public interface InterfaceService extends IService<Interface> {
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.Scene;
import com.baomidou.mybatisplus.extension.service.IService;
public interface SceneService extends IService<Scene> {
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.SceneTestcaseReport;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Map;
public interface SceneTestcaseReportService extends IService<SceneTestcaseReport> {
Map<String, Object> getSceneTestcaseReportListByNamespace(String namespace, Integer moduleId, Integer pageNum, Integer pageSize);
IPage<Map<String, Object>> getSceneTestcaseReportGroupByBatch(String namespace, Integer projectId, Integer pageNum, Integer pageSize);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.SceneTestcase;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
public interface SceneTestcaseService extends IService<SceneTestcase> {
String executeSceneTestcase(String namespace, Integer sceneId, String batch);
IPage<SceneTestcase> getSceneTestcaseList(Integer projectId, Integer pageNum, Integer pageSize);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.TestcaseReport;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Map;
public interface TestcaseReportService extends IService<TestcaseReport> {
Map<String, Object> getTestcaseReportByNamespace(String namespace, Integer projectId, Integer pageNum, Integer pageSize);
IPage<Map<String, Object>> getTestcaseReportGroupByBatch(String namespace, Integer moduleId, Integer pageNum, Integer pageSize);
}
package cn.qg.holmes.service.auto;
import cn.qg.holmes.entity.auto.Testcase;
import com.baomidou.mybatisplus.extension.service.IService;
public interface TestcaseService extends IService<Testcase> {
String singleTestcaseExecutor(String namespace, Integer testcaseId, String batch);
String executeTestcaseByModuleId(String namespace, Integer moduleId, String batch);
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.AutoModule;
import cn.qg.holmes.mapper.auto.AutoModuleMapper;
import cn.qg.holmes.service.auto.AutoModuleService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AutoModuleServiceImpl extends ServiceImpl<AutoModuleMapper, AutoModule> implements AutoModuleService {
@Autowired
AutoModuleMapper autoModuleMapper;
@Override
public IPage<AutoModule> getAutoModuleList(Integer pageNum, Integer pageSize) {
IPage<AutoModule> page = new Page<>(pageNum, pageSize);
return autoModuleMapper.getAutoModuleList(page);
}
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.AutoProject;
import cn.qg.holmes.mapper.auto.AutoProjectMapper;
import cn.qg.holmes.service.auto.AutoProjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class AutoProjectServiceImpl extends ServiceImpl<AutoProjectMapper, AutoProject> implements AutoProjectService {
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.service.auto.AutoUtilsService;
import cn.qg.holmes.utils.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.jayway.jsonpath.JsonPath;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* @author libo
* created at 2021-03-30
*/
@Service
@Slf4j
public class AutoUtilsServiceImpl implements AutoUtilsService {
@Autowired
RedisUtils redisUtils;
/**
* 将请求headers中的变量替换成对应的值
* @param headers 请求头json
* @param variables 参数json
* @return
*/
public Map<String, String> replaceHeaders(String headers, String variables, UUID uuid) {
log.info("开始执行请求头替换!");
Map<String, String> headersMap = JSON.parseObject(headers, Map.class);
Map<String, String> varMap = JSON.parseObject(variables, Map.class);
log.info("替换之前的headers:{}", headersMap);
log.info("参数列表:{}", varMap);
for (String key: varMap.keySet()) {
String value = varMap.get(key);
headersMap.put(key, redisUtils.get(uuid + "_" + value.substring(1)).toString());
}
log.info("替换之后的headers:{}", headersMap);
return headersMap;
}
/**
* 将请求体中的变量替换成对应的值
* @param parameters 请求参数json
* @param variables 变量json
* @return 替换后的参数Map
*/
public Map<String, String> replaceParameters(String parameters, String variables, UUID uuid) {
log.info("开始执行请求参数替换!");
Map<String, String> parameterMap = JSON.parseObject(parameters, Map.class);
Map<String, String> varMap = JSON.parseObject(variables, Map.class);
log.info("替换之前的参数:{}", parameterMap);
log.info("参数列表:{}", varMap);
for (String key: varMap.keySet()) {
String value = varMap.get(key);
parameterMap.put(key, redisUtils.get(uuid + "_" + value.substring(1)).toString());
}
log.info("替换之后的参数:{}", parameterMap);
return parameterMap;
}
/**
* 将响应中的值解析出来并存储到redis值
* @param response 响应json
* @param extract 解析的字段及保存到redis的key
* @return true-解析成功,false-解析失败
*/
public boolean extractResponse(String response, String extract, UUID uuid) {
Map<String, String> extractMap = JSON.parseObject(extract, Map.class);
try {
for (String key: extractMap.keySet()) {
String value = extractMap.get(key);
String redisKey = uuid + "_" + key;
redisUtils.set(redisKey, JsonPath.read(response, value));
redisUtils.expire(redisKey, 120);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 响应断言
* @return
*/
public boolean assertResponse(String response, List<Map> validateList) {
for (Map<String, String> map: validateList) {
String comparator = map.get("comparator");
String checkpoint = JsonPath.read(response, map.get("check")).toString();
String expectValue = map.get("expect");
boolean result = singleAssertResponse(response, comparator, checkpoint, expectValue);
if (!result) {
return false;
}
}
return true;
}
/**
*
* @param response
* @param comparator
* @param checkpoint
* @param expectValue
* @return
*/
public boolean singleAssertResponse(String response, String comparator, String checkpoint, String expectValue) {
switch (comparator) {
case "eq":
return checkpoint.equals(expectValue);
case "gt":
return Integer.parseInt(checkpoint) > Integer.parseInt(expectValue);
case "lt":
return Integer.parseInt(checkpoint) < Integer.parseInt(expectValue);
case "neq":
return !checkpoint.equals(expectValue);
default:
log.info("暂不支持该比较符号:{}", comparator);
break;
}
return false;
}
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.Interface;
import cn.qg.holmes.mapper.auto.InterfaceMapper;
import cn.qg.holmes.service.auto.InterfaceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class InterfaceServiceImpl extends ServiceImpl<InterfaceMapper, Interface> implements InterfaceService {
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.Scene;
import cn.qg.holmes.mapper.auto.SceneMapper;
import cn.qg.holmes.service.auto.SceneService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class SceneServiceImpl extends ServiceImpl<SceneMapper, Scene> implements SceneService {
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.SceneTestcaseReport;
import cn.qg.holmes.mapper.auto.SceneTestcaseReportMapper;
import cn.qg.holmes.service.auto.SceneTestcaseReportService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class SceneTestcaseReportServiceImpl extends ServiceImpl<SceneTestcaseReportMapper, SceneTestcaseReport> implements SceneTestcaseReportService {
@Autowired
SceneTestcaseReportMapper sceneTestcaseReportMapper;
@Override
public Map<String, Object> getSceneTestcaseReportListByNamespace(String namespace, Integer moduleId, Integer pageNum, Integer pageSize) {
QueryWrapper<SceneTestcaseReport> queryWrapper = new QueryWrapper<>();
if (namespace != null && !namespace.isEmpty()) {
queryWrapper.eq("namespace", namespace);
}
if (moduleId != null) {
queryWrapper.eq("module_id", moduleId);
}
queryWrapper.orderByDesc("id");
Page<SceneTestcaseReport> page = new Page<>(pageNum, pageSize);
IPage<SceneTestcaseReport> iPage = sceneTestcaseReportMapper.selectPage(page, queryWrapper);
Map<String, Object> map = new HashMap<>();
map.put("total", iPage.getTotal());
map.put("list", iPage.getRecords());
return map;
}
@Override
public IPage<Map<String, Object>> getSceneTestcaseReportGroupByBatch(String namespace, Integer projectId, Integer pageNum, Integer pageSize) {
IPage<Map<String, Object>> page = new Page<>(pageNum, pageSize);
return sceneTestcaseReportMapper.getSceneTestcaseReportGroupByBatch(namespace, projectId, page);
}
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.AutoModule;
import cn.qg.holmes.entity.auto.Interface;
import cn.qg.holmes.entity.auto.SceneTestcase;
import cn.qg.holmes.entity.auto.SceneTestcaseReport;
import cn.qg.holmes.mapper.auto.SceneTestcaseMapper;
import cn.qg.holmes.service.auto.*;
import cn.qg.holmes.utils.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author libo
* created at 2021-03-30
*/
@Service
@Slf4j
public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, SceneTestcase> implements SceneTestcaseService {
@Autowired
SceneTestcaseMapper sceneTestcaseMapper;
@Autowired
TestcaseService testcaseService;
@Autowired
InterfaceService interfaceService;
@Autowired
AutoModuleService autoModuleService;
@Autowired
AutoUtilsService autoUtilsService;
@Autowired
SceneTestcaseReportService sceneTestcaseReportService;
@Autowired
SceneService sceneService;
@Override
public String executeSceneTestcase(String namespace, Integer sceneId, String batch) {
UUID uuid = UUID.randomUUID();
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("scene_id", sceneId);
queryWrapper.orderByAsc("sequence");
List<SceneTestcase> sceneTestcaseList = sceneTestcaseMapper.selectList(queryWrapper);
List<Map<String, Object>> resultList = new ArrayList<>();
for (SceneTestcase sceneTestcase: sceneTestcaseList) {
resultList.add(JSON.parseObject(sceneTestcaseExecution(namespace, sceneId, sceneTestcase.getInterfaceId(), uuid, batch), Map.class));
}
return JSON.toJSONString(resultList);
}
/**
* 获取场景用例列表
* @param projectId 项目id
* @param pageNum 第几页
* @param pageSize 每页多少条
* @return
*/
@Override
public IPage<SceneTestcase> getSceneTestcaseList(Integer projectId, Integer pageNum, Integer pageSize) {
IPage<SceneTestcase> page = new Page<>(pageNum, pageSize);
return sceneTestcaseMapper.getSceneTestcaseList(projectId, page);
}
public String sceneTestcaseExecution(String namespace, Integer sceneId, Integer interfaceId, UUID uuid, String batch) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("scene_id", sceneId);
queryWrapper.eq("interface_id", interfaceId);
SceneTestcase sceneTestcase = sceneTestcaseMapper.selectOne(queryWrapper);
Interface anInterface = interfaceService.getById(interfaceId);
AutoModule autoModule = autoModuleService.getById(anInterface.getModuleId());
String domain = autoModule.getDomain();
String url = domain.replace("${NAMESPACE}", namespace) + anInterface.getUrl();
log.info("开始执行接口:{}", url);
String method = anInterface.getMethod().toUpperCase();
String paramType = anInterface.getParamType();
String interfaceName = anInterface.getName();
String headers = sceneTestcase.getHeaders();
String parameters = sceneTestcase.getParameters();
String variables = sceneTestcase.getVariables();
String extract = sceneTestcase.getExtract();
String validate = sceneTestcase.getValidate();
Map<String, String> parameterMap = JSON.parseObject(parameters, Map.class);
Map<String, String> headersMap = JSON.parseObject(headers, Map.class);
// 使用变量替换headers
if (variables != null && !variables.isEmpty() && headers != null && !headers.isEmpty()) {
headersMap = autoUtilsService.replaceHeaders(headers, variables, uuid);
}
// 使用变量替换参数
if (variables != null && !variables.isEmpty() && parameters != null && !parameters.isEmpty()) {
parameterMap = autoUtilsService.replaceParameters(parameters, variables, uuid);
}
// 创建断言列表
List<Map> validateList = new ArrayList<>();
if (validate != null && !validate.isEmpty()) {
validateList = JSON.parseArray(validate, Map.class);
}
String response = "";
Long startTime = System.currentTimeMillis();
switch (method) {
case "GET":
response = HttpClientUtils.doGet(url, headersMap, parameterMap);
break;
case "POST":
if (paramType.equals("json")) {
response = HttpClientUtils.doPostJson(url, headersMap, JSON.toJSONString(parameterMap));
} else if (paramType.equals("form")) {
response = HttpClientUtils.doPost(url, headersMap, parameterMap);
}
break;
default:
log.info("暂不支持该请求方法:{}", method);
break;
}
Long endTime = System.currentTimeMillis();
Long elapsedTime = endTime - startTime;
log.info("本次接口的响应为:{}", response);
log.info("本次接口执行时间:{}", elapsedTime);
// 进行断言
boolean assertResult = true;
if (!validateList.isEmpty()) {
assertResult = autoUtilsService.assertResponse(response, validateList);
}
// 解析响应
if (extract != null && !extract.isEmpty()) {
autoUtilsService.extractResponse(response, extract, uuid);
}
Map<String, Object> map = new HashMap<>();
map.put("url", url);
map.put("name", interfaceName);
map.put("headers", headersMap);
map.put("parameters", parameterMap);
map.put("assertResult", assertResult);
map.put("response", JSON.parseObject(response, Map.class));
map.put("elapsedTime", elapsedTime);
// 插入测试报告
SceneTestcaseReport sceneTestcaseReport = new SceneTestcaseReport();
sceneTestcaseReport.setSceneId(sceneId);
sceneTestcaseReport.setSceneTestcaseId(sceneTestcase.getId());
sceneTestcaseReport.setSequence(sceneTestcase.getSequence());
sceneTestcaseReport.setUrl(url);
sceneTestcaseReport.setHeaders(JSON.toJSONString(headersMap));
sceneTestcaseReport.setParameters(JSON.toJSONString(parameterMap));
if (assertResult) {
sceneTestcaseReport.setStatus("pass");
} else {
sceneTestcaseReport.setStatus("fail");
}
sceneTestcaseReport.setElapsedTime(elapsedTime);
sceneTestcaseReport.setResponse(response);
sceneTestcaseReport.setValidate(validate);
sceneTestcaseReport.setBatch(batch);
sceneTestcaseReport.setProjectId(sceneService.getById(sceneId).getProjectId());
sceneTestcaseReport.setNamespace(namespace);
log.info("保存测试报告:{}", sceneTestcaseReport);
sceneTestcaseReportService.save(sceneTestcaseReport);
return JSON.toJSONString(map);
}
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.TestcaseReport;
import cn.qg.holmes.mapper.auto.TestcaseReportMapper;
import cn.qg.holmes.service.auto.TestcaseReportService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class TestcaseReportServiceImpl extends ServiceImpl<TestcaseReportMapper, TestcaseReport> implements TestcaseReportService {
@Autowired
TestcaseReportMapper testcaseReportMapper;
@Override
public Map<String, Object> getTestcaseReportByNamespace(String namespace, Integer projectId, Integer pageNum, Integer pageSize) {
QueryWrapper<TestcaseReport> testcaseReportQueryWrapper = new QueryWrapper<>();
if (namespace != null && !namespace.isEmpty()) {
testcaseReportQueryWrapper.eq("namespace", namespace);
}
if (projectId != null) {
testcaseReportQueryWrapper.eq("project_id", projectId);
}
testcaseReportQueryWrapper.orderByDesc("id");
Page<TestcaseReport> page = new Page<>(pageNum, pageSize);
IPage<TestcaseReport> iPage = testcaseReportMapper.selectPage(page, testcaseReportQueryWrapper);
Map<String, Object> map = new HashMap<>();
map.put("total", iPage.getTotal());
map.put("list", iPage.getRecords());
return map;
}
@Override
public IPage<Map<String, Object>> getTestcaseReportGroupByBatch(String namespace, Integer moduleId, Integer pageNum, Integer pageSize) {
IPage<Map<String, Object>> page = new Page<>(pageNum, pageSize);
return testcaseReportMapper.getTestcaseReportGroupByBatch(namespace, moduleId, page);
}
}
package cn.qg.holmes.service.auto.impl;
import cn.qg.holmes.entity.auto.AutoModule;
import cn.qg.holmes.entity.auto.Interface;
import cn.qg.holmes.entity.auto.Testcase;
import cn.qg.holmes.entity.auto.TestcaseReport;
import cn.qg.holmes.mapper.auto.TestcaseMapper;
import cn.qg.holmes.service.auto.*;
import cn.qg.holmes.utils.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author libo
* created at 2021-03-30
*/
@Service
@Slf4j
public class TestcaseServiceImpl extends ServiceImpl<TestcaseMapper, Testcase> implements TestcaseService {
@Autowired
TestcaseMapper testcaseMapper;
@Autowired
InterfaceService interfaceService;
@Autowired
AutoModuleService autoModuleService;
@Autowired
AutoUtilsService autoUtilsService;
@Autowired
TestcaseReportService testcaseReportService;
/**
* 执行单接口用例
* @param namespace 环境
* @param testcaseId 用例id
* @return
*/
@Override
public String singleTestcaseExecutor(String namespace, Integer testcaseId, String batch) {
Testcase testcase = testcaseMapper.selectById(testcaseId);
Interface anInterface = interfaceService.getById(testcase.getInterfaceId());
AutoModule autoModule = autoModuleService.getById(anInterface.getModuleId());
String domain = autoModule.getDomain();
String url = domain.replace("${NAMESPACE}", namespace) + anInterface.getUrl();
String method = anInterface.getMethod().toUpperCase();
String paramType = anInterface.getParamType();
String headers = testcase.getHeaders();
String parameters = testcase.getParameters();
String testcaseName = testcase.getName();
String variables = testcase.getVariables();
String extract = testcase.getExtract();
String validate = testcase.getValidate();
// 参数准备
Map<String, String> headersMap = JSON.parseObject(headers, Map.class);
Map<String, String> parameterMap = JSON.parseObject(parameters, Map.class);
// 使用变量替换headers
// if (variables != null && !variables.isEmpty() && headers != null && !headers.isEmpty()) {
// headersMap = autoUtilsService.replaceHeaders(headers, variables);
// }
// // 使用变量替换参数
// if (variables != null && !variables.isEmpty() && parameters != null && !parameters.isEmpty()) {
// parameterMap = autoUtilsService.replaceParameters(parameters, variables);
// }
// 创建断言列表
List<Map> validateList = new ArrayList<>();
if (validate != null && !validate.isEmpty()) {
validateList = JSON.parseArray(validate, Map.class);
}
String response = "";
Long startTime = System.currentTimeMillis();
// 发起http请求
switch (method) {
case "GET":
response = HttpClientUtils.doGet(url, headersMap, parameterMap);
break;
case "POST":
if (paramType.equals("json")) {
response = HttpClientUtils.doPostJson(url, headersMap, JSON.toJSONString(parameterMap));
} else if (paramType.equals("form")) {
response = HttpClientUtils.doPost(url, headersMap, parameterMap);
}
break;
default:
log.info("暂不支持该请求方法:{}", method);
break;
}
Long endTime = System.currentTimeMillis();
Long elapsedTime = endTime - startTime;
log.info("用例:{}, 返回为:{}", testcaseName, response);
log.info("本次接口执行时间:{}", elapsedTime);
// 进行断言
boolean assertResult = true;
if (!validateList.isEmpty()) {
assertResult = autoUtilsService.assertResponse(response, validateList);
}
// 解析响应
// if (extract != null && !extract.isEmpty()) {
// autoUtilsService.extractResponse(response, extract);
// }
Map<String, Object> map = new HashMap<>();
map.put("url", url);
map.put("name", testcaseName);
map.put("headers", headersMap);
map.put("parameters", parameterMap);
map.put("assertResult", assertResult);
map.put("response", JSON.parseObject(response, Map.class));
map.put("elapsedTime", elapsedTime);
// 插入测试报告
TestcaseReport testcaseReport = new TestcaseReport();
testcaseReport.setTestcaseId(testcaseId);
testcaseReport.setHeaders(JSON.toJSONString(headersMap));
testcaseReport.setParameters(JSON.toJSONString(parameterMap));
testcaseReport.setResponse(response);
testcaseReport.setValidate(validate);
if (assertResult) {
testcaseReport.setStatus("pass");
} else {
testcaseReport.setStatus("fail");
}
testcaseReport.setElapsedTime(elapsedTime);
testcaseReport.setBatch(batch);
testcaseReport.setModuleId(testcase.getModuleId());
testcaseReport.setNamespace(namespace);
testcaseReport.setUrl(url);
testcaseReportService.save(testcaseReport);
return JSON.toJSONString(map);
}
/**
* 执行某个模块下所有用例
* @param namespace 环境
* @param moduleId 模块id
* @param batch 执行批次
* @return
*/
@Override
public String executeTestcaseByModuleId(String namespace, Integer moduleId, String batch) {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("module_id", moduleId);
List<Testcase> testcaseList = testcaseMapper.selectList(queryWrapper);
List<Map> resultList = new ArrayList<>();
for (Testcase testcase: testcaseList) {
String response = singleTestcaseExecutor(namespace, testcase.getId(), batch);
resultList.add(JSON.parseObject(response, Map.class));
}
return JSON.toJSONString(resultList);
}
}
package cn.qg.holmes.utils; package cn.qg.holmes.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
/** /**
...@@ -9,8 +10,8 @@ public class BankCardUtils { ...@@ -9,8 +10,8 @@ public class BankCardUtils {
public static String getCardCode(String cardNo) { public static String getCardCode(String cardNo) {
String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=" + cardNo + "&cardBinCheck=true"; String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardNo=" + cardNo + "&cardBinCheck=true";
JSONObject resposne = HttpClientUtils.doGetReturnJson(url); String resposne = HttpClientUtils.doGet(url);
return resposne.get("bank").toString(); return JSON.parseObject(resposne).get("bank").toString();
} }
public static void main(String[] args) { public static void main(String[] args) {
......
package cn.qg.holmes.utils; package cn.qg.holmes.utils;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.HashMap; import java.util.HashMap;
...@@ -11,11 +10,12 @@ import java.util.Map; ...@@ -11,11 +10,12 @@ import java.util.Map;
public class DingdingUtils { public class DingdingUtils {
public static boolean sendToDingding(String jsonString, String webhook) { public static boolean sendToDingding(String jsonString, String webhook) {
Map<String, Object> headers = new HashMap<>(); Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json; charset=utf-8"); headers.put("Content-Type", "application/json; charset=utf-8");
JSONObject result = HttpClientUtils.doPostJson(webhook, jsonString, headers); String result = HttpClientUtils.doPostJson(webhook, headers, jsonString);
log.info("发送给钉钉: {}, 内容:{}, 钉钉返回结果:{}", webhook, jsonString, result); log.info("发送给钉钉: {}, 内容:{}, 钉钉返回结果:{}", webhook, jsonString, result);
return result.get("errmsg").equals("ok"); Map<String, String> resultMap = JSON.parseObject(result, Map.class);
return resultMap.get("errmsg").equals("ok");
} }
public static String buildMarkdownMsg(String key, String summary, String creator, String assignee, String priority, String module) { public static String buildMarkdownMsg(String key, String summary, String creator, String assignee, String priority, String module) {
...@@ -33,4 +33,9 @@ public class DingdingUtils { ...@@ -33,4 +33,9 @@ public class DingdingUtils {
markdown.put("markdown", content); markdown.put("markdown", content);
return JSON.toJSONString(markdown); return JSON.toJSONString(markdown);
} }
public static void main(String[] args) {
String markdown = buildMarkdownMsg("YXM-1499", "【羊小咩v7.6.00】【VCC首次交易率提升专题】巴拉巴拉", "黎博", "于巧玲", "p1", "kddsp");
sendToDingding(markdown, "https://oapi.dingtalk.com/robot/send?access_token=835663338d638e40daaf3ab358af741ef0680a826a962c91bedc53b149d85ee1");
}
} }
package cn.qg.holmes.utils; package cn.qg.holmes.utils;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
...@@ -18,290 +16,204 @@ import org.apache.http.message.BasicNameValuePair; ...@@ -18,290 +16,204 @@ import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.net.URI;
import java.net.URISyntaxException; import java.util.ArrayList;
import java.util.*; import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* HttpClient 工具类
* @author libo * @author libo
*/ */
@Slf4j
public class HttpClientUtils { public class HttpClientUtils {
private static final CloseableHttpClient client = HttpClients.createDefault();
/** // 编码格式。发送编码格式统一用UTF-8
* 不带参数的GET请求 private static final String ENCODING = "UTF-8";
* @param url 请求的url
* @return json
*/
public static JSONObject doGetReturnJson(String url) {
JSONObject jsonResult = new JSONObject();
HttpGet get = new HttpGet(url);
try {
CloseableHttpResponse response = client.execute(get);
HttpEntity httpEntity = response.getEntity();
String respStr = EntityUtils.toString(httpEntity, "utf-8");
jsonResult = JSONObject.parseObject(respStr);
} catch (IOException e) {
e.printStackTrace();
}
return jsonResult;
}
/**
* 不带参数的GET请求
* @param url 请求的url
* @return html代码
*/
public static String doGetReturnHtml(String url) {
String strResult = null;
HttpGet get = new HttpGet(url);
try {
CloseableHttpResponse response = client.execute(get);
HttpEntity httpEntity = response.getEntity();
strResult = EntityUtils.toString(httpEntity, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
return strResult;
}
/** // 设置连接超时时间,单位毫秒。
* 带参数的GET请求 private static final int CONNECT_TIMEOUT = 6000;
* @param url 请求url
* @param params 请求参数
* @param headers 请求头
* @throws URISyntaxException
* @return
*/
public static String doGetReturnHtml(String url, Map<String, Object> params, Map<String, Object> headers) throws URISyntaxException {
URIBuilder uriBuilder = new URIBuilder(url);
String strResult = null;
// 设置请求参数
if (params != null && !params.isEmpty()) {
Set<String> keySet = params.keySet();
for (String key : keySet) {
uriBuilder.setParameter(key, params.get(key).toString());
}
}
HttpGet get = new HttpGet(uriBuilder.build());
// 设置请求头
if (headers != null && !headers.isEmpty()) {
Set<String> keySet = headers.keySet();
for (String s : keySet) {
get.addHeader(s, headers.get(s).toString());
}
}
try {
CloseableHttpResponse response = client.execute(get);
HttpEntity httpEntity = response.getEntity();
strResult = EntityUtils.toString(httpEntity, "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
return strResult;
}
/** // 请求获取数据的超时时间(即响应时间),单位毫秒。
* 带参数的GET请求 private static final int SOCKET_TIMEOUT = 6000;
* @param url url
* @param params 参数
* @param headers 请求头
* @return json
* @throws URISyntaxException
*/
public static JSONObject doGetReturnJson(String url, Map<String, Object> params, Map<String, Object> headers) throws URISyntaxException {
JSONObject jsonResult = new JSONObject();
URIBuilder uriBuilder = new URIBuilder(url);
// 设置参数
if (params != null && !params.isEmpty()) {
Set<String> keySet = params.keySet();
for (String key : keySet) {
uriBuilder.setParameter(key, params.get(key).toString());
}
}
HttpGet get = new HttpGet(uriBuilder.build());
if (headers != null && !headers.isEmpty()) {
Set<String> keySet = headers.keySet();
for (String s : keySet) {
get.addHeader(s, headers.get(s).toString());
}
}
try {
CloseableHttpResponse response = client.execute(get);
HttpEntity httpEntity = response.getEntity();
String respStr = EntityUtils.toString(httpEntity, "utf-8");
jsonResult = JSONObject.parseObject(respStr);
} catch (IOException e) {
e.printStackTrace();
}
return jsonResult;
}
/** /**
* 带参数的post请求 * http get 请求
* @param url * @param url
* @param headers
* @param params * @param params
* @return * @return
*/ */
public static JSONObject doPost(String url, String params) { public static String doGet(String url, Map<String, String> headers, Map<String, String> params) {
JSONObject jsonResult = new JSONObject();
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
String resultString = "";
try { try {
HttpPost post = new HttpPost(url); URIBuilder uriBuilder = new URIBuilder(url);
List<NameValuePair> list = new ArrayList<>(); // 设置请求参数
if (StringUtils.isNotEmpty(params)) { if (params != null) {
String[] splitStrings = params.split("&"); for (String key: params.keySet()) {
for (String splitString : splitStrings) { uriBuilder.addParameter(key, params.get(key));
String[] split = splitString.split("=");
list.add(new BasicNameValuePair(split[0], split[1]));
} }
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "utf-8");
post.setEntity(urlEncodedFormEntity);
} }
CloseableHttpResponse response = client.execute(post); URI uri = uriBuilder.build();
HttpEntity responseEntity = response.getEntity();
String responseString = EntityUtils.toString(responseEntity, "utf-8"); // 创建Http Get 请求
HttpGet httpGet = new HttpGet(uri);
// 设置请求超时时间
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpGet.setConfig(requestConfig);
// 设置请求头
setHeader(headers, httpGet);
// 执行http请求
httpResponse = httpClient.execute(httpGet);
resultString = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
} catch (Exception e) {
e.printStackTrace();
} finally {
try { try {
jsonResult = JSONObject.parseObject(responseString); // 释放资源
} catch (JSONException e) { if (httpResponse != null) {
jsonResult.put("content", responseString); httpResponse.close();
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
} }
} catch (IOException e) {
e.printStackTrace();
} }
return jsonResult; return resultString;
} }
public static JSONObject doPost(String url, Map<String, Object> params) { // 不带参数的get请求
JSONObject jsonResult = new JSONObject(); public static String doGet(String url) {
try { return doGet(url, null, null);
HttpPost post = new HttpPost(url); }
List list = new ArrayList();
if (params != null && !params.isEmpty()) {
Set<String> keySet = params.keySet();
for (String key : keySet) {
list.add(new BasicNameValuePair(key, params.get(key).toString()));
}
UrlEncodedFormEntity urlEncodedFormEntity =
new UrlEncodedFormEntity(list, "utf-8");
post.setEntity(urlEncodedFormEntity);
}
CloseableHttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
String respEntity = EntityUtils.toString(entity, "utf-8");
try {
jsonResult = JSONObject.parseObject(respEntity);
} catch (JSONException e) {
// e.printStackTrace();
jsonResult.put("content", respEntity.toString());
}
} catch (IOException e) { // 不带headers的get请求
e.printStackTrace(); public static String doGet(String url, Map<String, String> params) {
} return doGet(url, null, params);
return jsonResult;
} }
public static JSONObject doPost(String url, Map<String, Object> params, Map<String, Object> headers) { /**
JSONObject jsonResult = new JSONObject(); * 发送POST请求,携带map格式的参数
String responseString = null; * @param url 请求地址
* @param headers 请求头
* @param params 请求参数,Map格式
* @return
*/
public static String doPost(String url, Map<String, String> headers, Map<String, String> params) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
String resultString = "";
try { try {
HttpPost post = new HttpPost(url); // 创建 HttpPost
List list = new ArrayList(); HttpPost httpPost = new HttpPost(url);
// 设置请求超时时间
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
httpPost.setConfig(requestConfig);
// 设置请求头
setHeader(headers, httpPost);
// 设置请求参数
if (params != null && !params.isEmpty()) { if (params != null && !params.isEmpty()) {
Set<String> keySet = params.keySet(); List<NameValuePair> nameValuePairs = new ArrayList<>();
for (String key : keySet) { for (String key: params.keySet()) {
list.add(new BasicNameValuePair(key, params.get(key).toString())); nameValuePairs.add(new BasicNameValuePair(key, params.get(key)));
}
UrlEncodedFormEntity urlEncodedFormEntity =
new UrlEncodedFormEntity(list, "utf-8");
post.setEntity(urlEncodedFormEntity);
}
if (headers != null && !headers.isEmpty()) {
Set<String> keySet = headers.keySet();
for (String s : keySet) {
post.addHeader(s, headers.get(s).toString());
} }
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODING));
} }
// 执行http请求
httpResponse = httpClient.execute(httpPost);
resultString = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
} catch (Exception e) {
e.printStackTrace();
} finally {
try { try {
CloseableHttpResponse response = client.execute(post); // 释放资源
HttpEntity responseEntity = response.getEntity(); if (httpResponse != null) {
responseString = EntityUtils.toString(responseEntity, "utf-8"); httpResponse.close();
jsonResult = JSONObject.parseObject(responseString); }
} catch (JSONException e) { httpClient.close();
// e.printStackTrace(); } catch (IOException e) {
jsonResult.put("content", responseString); e.printStackTrace();
} }
} catch (IOException e) {
e.printStackTrace();
} }
return jsonResult; return resultString;
} }
public static JSONObject doPostJson(String url, String params) { // 不带参数的post请求
JSONObject result = new JSONObject(); public static String doPost(String url) {
HttpPost httpPost = new HttpPost(url); return doPost(url, null, null);
if (StringUtils.isNotEmpty(params)) { }
StringEntity stringEntity = new StringEntity(params, "utf-8");
httpPost.setEntity(stringEntity); // 不带headers的post请求
} public static String doPost(String url, Map<String, String> params) {
// if (StringUtils.isNotEmpty(headers)) { return doPost(url, null, params);
// httpPost.setHeader("Content-Type", "application/json"); }
// }
httpPost.setHeader("Content-Type", "application/json"); /**
* 发送post请求,携带json类型数据
* @param url 请求地址
* @param headers 请求头
* @param json json格式参数
* @return
*/
public static String doPostJson(String url, Map<String, String> headers, String json) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse httpResponse = null;
String resultString = "";
try { try {
CloseableHttpResponse response = client.execute(httpPost); // 创建Http Post请求
HttpEntity responseEntity = response.getEntity(); HttpPost httpPost = new HttpPost(url);
String responseString = EntityUtils.toString(responseEntity, "utf-8"); // 创建请求内容
result = JSONObject.parseObject(responseString); StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
} catch (IOException e) { httpPost.setEntity(entity);
// 设置请求头
setHeader(headers, httpPost);
httpResponse = httpClient.execute(httpPost);
resultString = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
try {
// 释放资源
if (httpResponse != null) {
httpResponse.close();
}
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
return result; return resultString;
} }
public static JSONObject doPostJson(String url, String params, Map<String, Object> headers) { /**
JSONObject result = new JSONObject(); * Description: 封装请求头
HttpPost httpPost = new HttpPost(url); * @param headers 请求头
if (StringUtils.isNotEmpty(params)) { * @param httpRequestBase HttpRequestBase
StringEntity stringEntity = new StringEntity(params, "utf-8"); */
httpPost.setEntity(stringEntity); public static void setHeader(Map<String, String> headers, HttpRequestBase httpRequestBase) {
} // 封装请求头
if (headers != null && !headers.isEmpty()) { if (headers != null && !headers.isEmpty()) {
Set<String> keySet = headers.keySet(); Set<String> keySet = headers.keySet();
for (String s : keySet) { for (String key : keySet) {
httpPost.addHeader(s, headers.get(s).toString()); // 设置到请求头到HttpRequestBase对象中
httpRequestBase.setHeader(key, headers.get(key));
} }
} }
try {
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
String responseString = EntityUtils.toString(responseEntity, "utf-8");
result = JSONObject.parseObject(responseString);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) throws UnsupportedEncodingException {
String url = "http://passportapi-qa.liangkebang.net/user/login/fastV1";
String phoneNo = "13712345678:0000";
Base64.Encoder encoder = Base64.getEncoder();
byte[] textByte = phoneNo.getBytes("UTF-8");
String phoneNoBase64 = encoder.encodeToString(textByte);
Map<String, Object> headers = new HashMap<>();
Map<String, Object> formData = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
headers.put("Authorization", "Verification " + phoneNoBase64);
formData.put("channelId", 1);
formData.put("createdFrom", 1);
formData.put("key", "xyqb");
formData.put("btRegisterChannelId", "");
formData.put("dimension", "");
formData.put("click_id", "");
JSONObject result = doPost(url, formData, headers);
System.out.println(result);
System.out.println(result.get("data"));
} }
} }
<?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="cn.qg.holmes.mapper.auto.AutoModuleMapper">
<select id="getAutoModuleList" resultType="cn.qg.holmes.entity.auto.AutoModule">
select a.*,
p.`name` as projectName
from `auto_module` a, auto_project p
where a.`project_id` = p.`id`
</select>
</mapper>
\ No newline at end of file
<?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="cn.qg.holmes.mapper.auto.SceneTestcaseMapper">
<select id="getSceneTestcaseList" resultType="cn.qg.holmes.entity.auto.SceneTestcase">
select stc.* from scene_testcase as stc
left join scene as sc ON stc.`scene_id`=sc.`id`
<if test="projectId != null">
WHERE sc.`id`=#{projectId}
</if>
</select>
</mapper>
\ No newline at end of file
<?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="cn.qg.holmes.mapper.auto.SceneTestcaseReportMapper">
<select id="getSceneTestcaseReportGroupByBatch" resultType="java.util.Map">
SELECT st.`scene_id` as sceneId, st.`batch`, st.`namespace`, st.`project_id` as projectId, pro.`name` as projectName, st.`create_time` as createTime from `scene_testcase_report` st
left join `auto_project` pro on st.`project_id` = pro.`id` WHERE 1=1
<if test="projectId != null and projectId !=''">
AND st.`project_id` = #{projectId}
</if>
<if test="namespace != null and namespace != ''">
AND st.`namespace` = #{namespace}
</if>
GROUP BY st.`batch`
</select>
</mapper>
\ No newline at end of file
<?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="cn.qg.holmes.mapper.auto.TestcaseReportMapper">
<select id="getTestcaseReportGroupByBatch" resultType="java.util.Map">
SELECT tr.`batch`,tr.`module_id` as moduleId, tr.`namespace`, tr.`create_time` as createTime, am.`name` as moduleName FROM `testcase_report` as tr
LEFT JOIN `auto_module` as am
ON tr.`module_id` = am.`id` WHERE 1=1
<if test="namespace != null and namespace != ''">
AND tr.`namespace` = #{namespace}
</if>
<if test="moduleId != null and moduleId != ''">
AND tr.`module_id` = #{moduleId}
</if>
</select>
</mapper>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment