This commit is contained in:
chenjianxing 2020-09-17 17:17:35 +08:00
commit 1b36e3302a
6 changed files with 77 additions and 30 deletions

View File

@ -6,7 +6,7 @@ import java.util.stream.Collectors;
public class TestCaseConstants { public class TestCaseConstants {
public static final int MAX_NODE_DEPTH = 5; public static final int MAX_NODE_DEPTH = 8;
public enum Type { public enum Type {
Functional("functional"), Performance("performance"), Aapi("api"); Functional("functional"), Performance("performance"), Aapi("api");

View File

@ -334,7 +334,12 @@ public class TestCaseService {
byte[] buff = new byte[1024]; byte[] buff = new byte[1024];
// 读取filename // 读取filename
String filePath = ClassLoader.getSystemResource("template/testcase.xmind").getPath(); String filePath = ClassLoader.getSystemResource("template/testcase.xmind").getPath();
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(filePath)));) { LogUtil.info("模版文件路径:"+filePath);
File file = new File(filePath);
if(file == null || !file.exists()){
LogUtil.info("模版模版下载失败:"+filePath);
}
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {
int i = bis.read(buff); int i = bis.read(buff);
while (i != -1) { while (i != -1) {
outputStream.write(buff, 0, buff.length); outputStream.write(buff, 0, buff.length);
@ -348,7 +353,7 @@ public class TestCaseService {
public void testCaseXmindTemplateExport(HttpServletResponse response) { public void testCaseXmindTemplateExport(HttpServletResponse response) {
try { try {
response.setContentType("application/vnd.ms-excel"); response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("思维导图用例模版", "UTF-8") + ".xmind"); response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("思维导图用例模版", "UTF-8") + ".xmind");
download(response); download(response);

View File

@ -21,6 +21,8 @@ import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.*; import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* 数据转换 * 数据转换
@ -51,18 +53,40 @@ public class XmindToTestCaseParser {
protected List<TestCaseExcelData> xmindDataList; protected List<TestCaseExcelData> xmindDataList;
// 递归处理案例数据 // 递归处理案例数据
private void makeXmind(StringBuffer processBuffer, String nodeId, int level, String nodePath, List<Attached> attacheds) { private void makeXmind(StringBuffer processBuffer, Attached parent, int level, String nodePath, List<Attached> attacheds) {
for (Attached item : attacheds) { for (Attached item : attacheds) {
if (!StringUtils.isEmpty(item.getTitle()) && item.getTitle().startsWith("tc")) { // 用例 if (isBlack(item.getTitle(), "(?:tc|tc)")) { // 用例
this.newTestCase(item.getTitle(), nodePath, item.getChildren() != null ? item.getChildren().getAttached() : null); item.setParent(parent);
this.newTestCase(item.getTitle(), parent.getPath(), item.getChildren() != null ? item.getChildren().getAttached() : null);
} else { } else {
nodePath = nodePath + "/" + item.getTitle(); nodePath = parent.getPath() + "/" + item.getTitle();
if (item.getChildren() != null && !item.getChildren().getAttached().isEmpty()) item.setPath(nodePath);
makeXmind(processBuffer, nodeId, level + 1, nodePath, item.getChildren().getAttached()); if (item.getChildren() != null && !item.getChildren().getAttached().isEmpty()) {
item.setParent(parent);
makeXmind(processBuffer, item, level + 1, nodePath, item.getChildren().getAttached());
}
} }
} }
} }
private boolean isBlack(String str, String regex) {
// regex = "(?:tc:|tc)"
if (StringUtils.isEmpty(str) || StringUtils.isEmpty(regex))
return false;
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher result = pattern.matcher(str);
return result.find();
}
private String replace(String str, String regex) {
if (StringUtils.isEmpty(str) || StringUtils.isEmpty(regex))
return str;
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher result = pattern.matcher(str);
str = result.replaceAll("");
return str;
}
// 获取步骤数据 // 获取步骤数据
public String getSteps(List<Attached> attacheds) { public String getSteps(List<Attached> attacheds) {
JSONArray jsonArray = new JSONArray(); JSONArray jsonArray = new JSONArray();
@ -95,7 +119,7 @@ public class XmindToTestCaseParser {
return; return;
} }
// 用例名称 // 用例名称
testCase.setName(tcArr[1].replace("tc:|tc", "")); testCase.setName(this.replace(tcArr[1], "tc:|tc|tc"));
if (!nodePath.startsWith("/")) { if (!nodePath.startsWith("/")) {
nodePath = "/" + nodePath; nodePath = "/" + nodePath;
@ -110,7 +134,7 @@ public class XmindToTestCaseParser {
String otArr[] = tcArr[0].split("-"); String otArr[] = tcArr[0].split("-");
for (int i = 0; i < otArr.length; i++) { for (int i = 0; i < otArr.length; i++) {
if (otArr[i].startsWith("P") || otArr[i].startsWith("p")) { if (otArr[i].startsWith("P") || otArr[i].startsWith("p")) {
testCase.setPriority(otArr[i]); testCase.setPriority(otArr[i].toUpperCase());
} else if (otArr[i].endsWith("功能测试")) { } else if (otArr[i].endsWith("功能测试")) {
testCase.setType("functional"); testCase.setType("functional");
} else if (otArr[i].endsWith("性能测试")) { } else if (otArr[i].endsWith("性能测试")) {
@ -121,20 +145,29 @@ public class XmindToTestCaseParser {
} }
} }
// 测试步骤处理 // 测试步骤处理
List<Attached> steps = new LinkedList<>();
if (attacheds != null && !attacheds.isEmpty()) { if (attacheds != null && !attacheds.isEmpty()) {
List<Attached> steps = new LinkedList<>();
attacheds.forEach(item -> { attacheds.forEach(item -> {
if (item.getTitle().startsWith("pc")) { if (isBlack(item.getTitle(), "(?:pc:|pc)")) {
testCase.setPrerequisite(item.getTitle().replaceAll("(?:pc:|pc)", "")); testCase.setPrerequisite(replace(item.getTitle(), "(?:pc:|pc)"));
} else if (item.getTitle().startsWith("rc")) { } else if (isBlack(item.getTitle(), "(?:rc:|rc)")) {
testCase.setRemark(item.getTitle().replaceAll("(?:rc:|rc)", "")); testCase.setRemark(replace(item.getTitle(), "(?:rc:|rc)"));
} else { } else {
steps.add(item); steps.add(item);
} }
}); });
if (!steps.isEmpty()) { }
testCase.setSteps(this.getSteps(steps)); if (!steps.isEmpty()) {
} testCase.setSteps(this.getSteps(steps));
} else {
JSONArray jsonArray = new JSONArray();
// 保持插入顺序判断用例是否有相同的steps
JSONObject step = new JSONObject(true);
step.put("num", 1);
step.put("desc", "");
step.put("result", "");
jsonArray.add(step);
testCase.setSteps(jsonArray.toJSONString());
} }
TestCaseExcelData compartData = new TestCaseExcelData(); TestCaseExcelData compartData = new TestCaseExcelData();
BeanUtils.copyBean(compartData, testCase); BeanUtils.copyBean(compartData, testCase);
@ -232,25 +265,27 @@ public class XmindToTestCaseParser {
// 获取思维导图内容 // 获取思维导图内容
String content = XmindParser.parseJson(file); String content = XmindParser.parseJson(file);
if (StringUtils.isEmpty(content) || content.split("(?:tc:|tc)").length == 1) { if (StringUtils.isEmpty(content) || content.split("(?:tc:|tc|TC:|TC|tc|TC)").length == 1) {
return Translator.get("import_xmind_not_found"); return Translator.get("import_xmind_not_found");
} }
if (!StringUtils.isEmpty(content) && content.split("(?:tc:|tc)").length > 500) { if (!StringUtils.isEmpty(content) && content.split("(?:tc:|tc|TC:|TC|tc|TC)").length > 500) {
return Translator.get("import_xmind_count_error"); return Translator.get("import_xmind_count_error");
} }
JsonRootBean root = JSON.parseObject(content, JsonRootBean.class); JsonRootBean root = JSON.parseObject(content, JsonRootBean.class);
if (root != null && root.getRootTopic() != null && root.getRootTopic().getChildren() != null) { if (root != null && root.getRootTopic() != null && root.getRootTopic().getChildren() != null) {
// 判断是模块还是用例 // 判断是模块还是用例
root.getRootTopic().getChildren().getAttached().forEach(item -> { for (Attached item : root.getRootTopic().getChildren().getAttached()) {
if (!StringUtils.isEmpty(item.getTitle()) && item.getTitle().startsWith("tc")) { // 用例 if (isBlack(item.getTitle(), "(?:tc:|tc|tc)")) { // 用例
this.newTestCase(item.getTitle(), "", item.getChildren() != null ? item.getChildren().getAttached() : null); return replace(item.getTitle(), "(?:tc:|tc|tc)") + "" + Translator.get("test_case_create_module_fail");
} else { } else {
item.setPath(item.getTitle()); item.setPath(item.getTitle());
if (item.getChildren() != null && !item.getChildren().getAttached().isEmpty()) if (item.getChildren() != null && !item.getChildren().getAttached().isEmpty()) {
makeXmind(processBuffer, null, 1, item.getPath(), item.getChildren().getAttached()); item.setPath(item.getTitle());
makeXmind(processBuffer, item, 1, item.getPath(), item.getChildren().getAttached());
}
} }
}); }
} }
if (StringUtils.isEmpty(process.toString()) && !testCaseWithBLOBs.isEmpty()) { if (StringUtils.isEmpty(process.toString()) && !testCaseWithBLOBs.isEmpty()) {
testCaseService.saveImportData(testCaseWithBLOBs, projectId); testCaseService.saveImportData(testCaseWithBLOBs, projectId);

View File

@ -12,6 +12,7 @@ public class Attached {
private String title; private String title;
private Notes notes; private Notes notes;
private String path; private String path;
private Attached parent;
private List<Comments> comments; private List<Comments> comments;
private Children children; private Children children;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -54,8 +54,8 @@
</el-row> </el-row>
<el-row class="import-row"> <el-row class="import-row">
<el-card :body-style="{ padding: '0px' }"> <el-card :body-style="{ padding: '0px' }">
<img src="../../../../../assets/xmind.jpg" width="700px" height="250px" <img src="../../../../../assets/xmind.jpg"
class="image"> class="testcase-import-img">
</el-card> </el-card>
</el-row> </el-row>
@ -247,7 +247,13 @@
} }
.testcase-import >>> .el-dialog { .testcase-import >>> .el-dialog {
width: 700px; width: 650px;
}
.testcase-import-img {
width: 614px;
height: 312px;
size: 200px;
} }